From 25f68107faf87d8c33cd65f63c0b66136dd9b869 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Tue, 16 Jun 2026 07:00:46 -0700 Subject: [PATCH 001/561] Fix unused variable 'moduleClass' in RCTTurboModuleManager.mm (#57221) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57221 changelog: [internal] Reviewed By: javache Differential Revision: D108605640 fbshipit-source-id: 2668aa853715cfb9ebdbe67cbaf45c092a0cb706 --- .../core/platform/ios/ReactCommon/RCTTurboModuleManager.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm index c3eefd433636..0078a1a826a3 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm @@ -333,7 +333,6 @@ - (instancetype)initWithBridgeProxy:(RCTBridgeProxy *)bridgeProxy * Use respondsToSelector: below to infer conformance to @protocol(RCTTurboModule). Using conformsToProtocol: is * expensive. */ - Class moduleClass = [module class]; if ([module respondsToSelector:@selector(getTurboModule:)]) { ObjCTurboModule::InitParams params = { .moduleName = moduleName, @@ -345,7 +344,7 @@ - (instancetype)initWithBridgeProxy:(RCTBridgeProxy *)bridgeProxy auto turboModule = [(id)module getTurboModule:params]; if (turboModule == nullptr) { - RCTLogError(@"TurboModule \"%@\"'s getTurboModule: method returned nil.", moduleClass); + RCTLogError(@"TurboModule \"%@\"'s getTurboModule: method returned nil.", [module class]); } _turboModuleCache.insert({moduleName, turboModule}); From 74fdfd1eab0812171fc60800b87ca22b3069e721 Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Tue, 16 Jun 2026 07:01:30 -0700 Subject: [PATCH 002/561] Remove deprecated Instance type aliases (Flow) (#57229) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57229 Remove the deprecated `PublicScrollViewInstance` and `PublicModalInstance` type aliases, replacing all remaining usages with the canonical `ScrollViewInstance` and `ModalInstance` types. NOTE: Existing equivalent types are **left alone** in the manual `.d.ts` sources (current TS API), as this is covered by the existing breaking migration notes for ref types under the Strict API. **Changes** - Delete `PublicScrollViewInstance` alias (ScrollView.js) - Delete `PublicModalInstance` alias (Modal.js) - Update `IntersectionObserverExplicitRootScroll.js` rn-tester example Changelog: [General][Removed] - **Strict TypeScript API**: Remove deprecated `PublicScrollViewInstance` and `PublicModalInstance` types. Use `ScrollViewInstance` and `ModalInstance` instead. Reviewed By: cipolleschi Differential Revision: D107268481 fbshipit-source-id: fbcd42378bf13919d5b14d5472f3c5ff4ffbbc9d --- .../Libraries/Components/ScrollView/ScrollView.js | 3 --- packages/react-native/Libraries/Modal/Modal.js | 3 --- .../IntersectionObserverExplicitRootScroll.js | 7 +++---- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js index 4f3a4fe3bb8f..babd9b985773 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js @@ -171,9 +171,6 @@ export interface ScrollViewInstance extends HostInstance, ScrollViewImperativeMethods {} -/** @deprecated Use ScrollViewInstance instead */ -export type PublicScrollViewInstance = ScrollViewInstance; - type InnerViewInstance = React.ElementRef; export type ScrollViewPropsIOS = Readonly<{ diff --git a/packages/react-native/Libraries/Modal/Modal.js b/packages/react-native/Libraries/Modal/Modal.js index c689e10fb43c..96a2bef7d0df 100644 --- a/packages/react-native/Libraries/Modal/Modal.js +++ b/packages/react-native/Libraries/Modal/Modal.js @@ -38,9 +38,6 @@ type ModalEventDefinitions = { export type ModalInstance = HostInstance; -/** @deprecated Use ModalInstance instead */ -export type PublicModalInstance = ModalInstance; - const ModalEventEmitter = Platform.OS === 'ios' && NativeModalManager != null ? new NativeEventEmitter( diff --git a/packages/rn-tester/js/examples/IntersectionObserver/IntersectionObserverExplicitRootScroll.js b/packages/rn-tester/js/examples/IntersectionObserver/IntersectionObserverExplicitRootScroll.js index bf8834465010..a00afde69c74 100644 --- a/packages/rn-tester/js/examples/IntersectionObserver/IntersectionObserverExplicitRootScroll.js +++ b/packages/rn-tester/js/examples/IntersectionObserver/IntersectionObserverExplicitRootScroll.js @@ -8,8 +8,7 @@ * @flow strict-local */ -import type {HostInstance} from 'react-native'; -import type {PublicScrollViewInstance} from 'react-native/Libraries/Components/ScrollView/ScrollView'; +import type {HostInstance, ScrollViewInstance} from 'react-native'; import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet'; import type IntersectionObserverType from 'react-native/src/private/webapis/intersectionobserver/IntersectionObserver'; @@ -42,8 +41,8 @@ component IntersectionObserverExplicitRootScrollExample() { const [observationRoot, setObservationRoot] = useState(null); const [showMargin, setShowMargin] = useState(true); - const roofRef: React.RefSetter = useCallback( - (rootNode: ?PublicScrollViewInstance) => { + const roofRef: React.RefSetter = useCallback( + (rootNode: ?ScrollViewInstance) => { if (rootNode != null) { setObservationRoot(rootNode); } From ea17ef8b882c231d4d0b08038045769ba4bac1c4 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Tue, 16 Jun 2026 07:17:30 -0700 Subject: [PATCH 003/561] Default fixDifferentiatorParentTagForUnflattenCase to true with MC opt-out (#57220) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57220 Flip the React Native feature flag `fixDifferentiatorParentTagForUnflattenCase` default to `true` so the differentiator `parentTag` fix is on by default across all platforms Changelog: [Internal] Wire fbios + fb4a to MobileConfig params so we can opt out server-side if needed. Because the MC defaults are `true`, the feature activates for all FB-app users on land; setting the param to `false` server-side is the kill switch. Reviewed By: zeyap Differential Revision: D108613362 fbshipit-source-id: 6ffa21774582d5b8d83192fc65a964142b87b88e --- .../featureflags/ReactNativeFeatureFlagsDefaults.kt | 4 ++-- .../featureflags/ReactNativeFeatureFlagsDefaults.h | 4 ++-- .../mounting/tests/DifferentiatorUnflattenTest.cpp | 12 ++++++++++-- .../featureflags/ReactNativeFeatureFlags.config.js | 2 +- .../private/featureflags/ReactNativeFeatureFlags.js | 4 ++-- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index 818eb338551d..e45d1aafaac6 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -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<<061d668cf04041f4d3d2f48f11dc739f>> + * @generated SignedSource<> */ /** @@ -127,7 +127,7 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableVirtualViewContainerStateExperimental(): Boolean = false - override fun fixDifferentiatorParentTagForUnflattenCase(): Boolean = false + override fun fixDifferentiatorParentTagForUnflattenCase(): Boolean = true override fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean = false diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index e0bebd010bc9..e6819ac0f5be 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -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<<8dfc52502bd539e5e43d547f895a6d33>> + * @generated SignedSource<> */ /** @@ -236,7 +236,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { } bool fixDifferentiatorParentTagForUnflattenCase() override { - return false; + return true; } bool fixMappingOfEventPrioritiesBetweenFabricAndReact() override { diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/tests/DifferentiatorUnflattenTest.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/tests/DifferentiatorUnflattenTest.cpp index 45ea4380e986..6e886866e16e 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/tests/DifferentiatorUnflattenTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/tests/DifferentiatorUnflattenTest.cpp @@ -27,9 +27,14 @@ namespace { class TestFlagsWithUnflattenFix : public ReactNativeFeatureFlagsDefaults { public: + explicit TestFlagsWithUnflattenFix(bool enabled) : enabled_(enabled) {} + bool fixDifferentiatorParentTagForUnflattenCase() override { - return true; + return enabled_; } + + private: + bool enabled_; }; } // namespace @@ -164,6 +169,9 @@ class DifferentiatorUnflattenTest : public ::testing::Test { TEST_F( DifferentiatorUnflattenTest, withoutFix_updateMutationHasWrongParentTag) { + ReactNativeFeatureFlags::dangerouslyForceOverride( + std::make_unique(false)); + applyUnflattenSetup_(); auto mutations = calculateMutations_(); @@ -186,7 +194,7 @@ TEST_F( // as parentTag, and StubViewTree::mutate() succeeds without assertion failure. TEST_F(DifferentiatorUnflattenTest, withFix_updateMutationHasCorrectParentTag) { ReactNativeFeatureFlags::dangerouslyForceOverride( - std::make_unique()); + std::make_unique(true)); applyUnflattenSetup_(); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 15976d671629..d8e33fe817e4 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -605,7 +605,7 @@ const definitions: FeatureFlagDefinitions = { ossReleaseStage: 'none', }, fixDifferentiatorParentTagForUnflattenCase: { - defaultValue: false, + defaultValue: true, metadata: { dateAdded: '2026-04-18', description: diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 403f339511aa..d1a25226a318 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -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<<609451fd0a38e0f8eaf685e7cf534e27>> + * @generated SignedSource<<3304b4ee2c718dbf4d56b607ea09054d>> * @flow strict * @noformat */ @@ -424,7 +424,7 @@ export const enableVirtualViewContainerStateExperimental: Getter = crea /** * Fix incorrect parentTag passed as parentTagForUpdate in the unflatten-unflatten branch of calculateShadowViewMutationsFlattener, which causes UPDATE mutations to reference a parent being created in the same batch. */ -export const fixDifferentiatorParentTagForUnflattenCase: Getter = createNativeFlagGetter('fixDifferentiatorParentTagForUnflattenCase', false); +export const fixDifferentiatorParentTagForUnflattenCase: Getter = createNativeFlagGetter('fixDifferentiatorParentTagForUnflattenCase', true); /** * Uses the default event priority instead of the discreet event priority by default when dispatching events from Fabric to React. */ From ac9cba3f7b5204fe2fe2b8e5d764783298a75c8d Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Tue, 16 Jun 2026 07:22:33 -0700 Subject: [PATCH 004/561] Add tight lineHeight descender example to TextExample.android.js (#57223) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57223 Adds a `gjpqy` example to the Text > lineHeight RNTester section that exercises `fontSize: 24, lineHeight: 24`. Pure example addition for the upcoming `CustomLineHeightSpan` descender-clipping fix, providing the surface for a jest-e2e screenshot regression test. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D108409230 fbshipit-source-id: acd97a92e6970e29b1a04090d14976336cdc4b37 --- .../js/examples/Text/TextExample.android.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/rn-tester/js/examples/Text/TextExample.android.js b/packages/rn-tester/js/examples/Text/TextExample.android.js index 090ced25e600..a88bef0bac79 100644 --- a/packages/rn-tester/js/examples/Text/TextExample.android.js +++ b/packages/rn-tester/js/examples/Text/TextExample.android.js @@ -1119,6 +1119,19 @@ function LineHeightExample(props: {}): React.Node { Continually expedite magnetic potentialities rather than client-focused interfaces. + + gjpqy + Date: Tue, 16 Jun 2026 07:26:44 -0700 Subject: [PATCH 005/561] Remove enableDifferentiatorMutationVectorPreallocation feature flag (#57224) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57224 The `enableDifferentiatorMutationVectorPreallocation` flag gated a mutation-vector pre-allocation optimization in the `Differentiator`. It was never ramped and is being removed. The flag defaulted to `false`, so this restores the pre-flag behavior by deleting the gated `reserve(...)` calls (an allocation hint with no effect on diffing results) and keeping the default `mutations.reserve(256)`. Removes the flag definition from `ReactNativeFeatureFlags.config.js`, the gated call sites in `Differentiator.cpp`, and the regenerated feature-flag files (via `yarn featureflags --update`). Changelog: [Internal] Reviewed By: javache Differential Revision: D108411519 fbshipit-source-id: 73844c54627545a111ad2bd83fa09171d87c3396 --- .../featureflags/ReactNativeFeatureFlags.kt | 8 +- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 +- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 +- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +- .../featureflags/ReactNativeFeatureFlags.h | 7 +- .../ReactNativeFeatureFlagsAccessor.cpp | 160 ++++++++---------- .../ReactNativeFeatureFlagsAccessor.h | 6 +- .../ReactNativeFeatureFlagsDefaults.h | 6 +- .../ReactNativeFeatureFlagsDynamicProvider.h | 11 +- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +- .../NativeReactNativeFeatureFlags.h | 4 +- .../renderer/mounting/Differentiator.cpp | 36 +--- .../ReactNativeFeatureFlags.config.js | 11 -- .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 21 files changed, 91 insertions(+), 242 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index da6e95c22538..7e98a407ee76 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -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<<7e91da9df64ce42424101d7d72356c4a>> + * @generated SignedSource<<5307fff9429956a3f3f2f54f2b6b00e7>> */ /** @@ -132,12 +132,6 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableDestroyShadowTreeRevisionAsync(): Boolean = accessor.enableDestroyShadowTreeRevisionAsync() - /** - * Pre-allocate mutation vectors in the Differentiator to reduce reallocation overhead during shadow view diffing. - */ - @JvmStatic - public fun enableDifferentiatorMutationVectorPreallocation(): Boolean = accessor.enableDifferentiatorMutationVectorPreallocation() - /** * When enabled a subset of components will avoid double measurement on Android. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index 6a4a6eb0c535..d43113255e58 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -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<<3c0e10dee93b76f3e66ca79d26f2b4f2>> + * @generated SignedSource<> */ /** @@ -37,7 +37,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var enableCppPropsIteratorSetterCache: Boolean? = null private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null - private var enableDifferentiatorMutationVectorPreallocationCache: Boolean? = null private var enableDoubleMeasurementFixAndroidCache: Boolean? = null private var enableEagerRootViewAttachmentCache: Boolean? = null private var enableExclusivePropsUpdateAndroidCache: Boolean? = null @@ -262,15 +261,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun enableDifferentiatorMutationVectorPreallocation(): Boolean { - var cached = enableDifferentiatorMutationVectorPreallocationCache - if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.enableDifferentiatorMutationVectorPreallocation() - enableDifferentiatorMutationVectorPreallocationCache = cached - } - return cached - } - override fun enableDoubleMeasurementFixAndroid(): Boolean { var cached = enableDoubleMeasurementFixAndroidCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index bd059df9c407..ce4b7dd3519e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -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<> + * @generated SignedSource<<6dc403c11108a657d48ec9573bee842f>> */ /** @@ -62,8 +62,6 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableDestroyShadowTreeRevisionAsync(): Boolean - @DoNotStrip @JvmStatic public external fun enableDifferentiatorMutationVectorPreallocation(): Boolean - @DoNotStrip @JvmStatic public external fun enableDoubleMeasurementFixAndroid(): Boolean @DoNotStrip @JvmStatic public external fun enableEagerRootViewAttachment(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index e45d1aafaac6..f90a51659f0f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -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<> + * @generated SignedSource<<452edce222866440ff3794deb178a7f4>> */ /** @@ -57,8 +57,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableDestroyShadowTreeRevisionAsync(): Boolean = false - override fun enableDifferentiatorMutationVectorPreallocation(): Boolean = false - override fun enableDoubleMeasurementFixAndroid(): Boolean = false override fun enableEagerRootViewAttachment(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 26fa9891b568..a2fd49e4990e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -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<> + * @generated SignedSource<<8ba7f19e8afe329937b1b36d3b83dbc5>> */ /** @@ -41,7 +41,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var enableCppPropsIteratorSetterCache: Boolean? = null private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null - private var enableDifferentiatorMutationVectorPreallocationCache: Boolean? = null private var enableDoubleMeasurementFixAndroidCache: Boolean? = null private var enableEagerRootViewAttachmentCache: Boolean? = null private var enableExclusivePropsUpdateAndroidCache: Boolean? = null @@ -283,16 +282,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } - override fun enableDifferentiatorMutationVectorPreallocation(): Boolean { - var cached = enableDifferentiatorMutationVectorPreallocationCache - if (cached == null) { - cached = currentProvider.enableDifferentiatorMutationVectorPreallocation() - accessedFeatureFlags.add("enableDifferentiatorMutationVectorPreallocation") - enableDifferentiatorMutationVectorPreallocationCache = cached - } - return cached - } - override fun enableDoubleMeasurementFixAndroid(): Boolean { var cached = enableDoubleMeasurementFixAndroidCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index c16a9d890a16..9402aed64871 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -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<> + * @generated SignedSource<<3a3f9014f644b6b964b50d0974a7b9b5>> */ /** @@ -57,8 +57,6 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableDestroyShadowTreeRevisionAsync(): Boolean - @DoNotStrip public fun enableDifferentiatorMutationVectorPreallocation(): Boolean - @DoNotStrip public fun enableDoubleMeasurementFixAndroid(): Boolean @DoNotStrip public fun enableEagerRootViewAttachment(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 7906170ed532..96c8d0d17419 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -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<> + * @generated SignedSource<<70e4f4b4bb3aa28a644ede80ceeb4fc3>> */ /** @@ -141,12 +141,6 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } - bool enableDifferentiatorMutationVectorPreallocation() override { - static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableDifferentiatorMutationVectorPreallocation"); - return method(javaProvider_); - } - bool enableDoubleMeasurementFixAndroid() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableDoubleMeasurementFixAndroid"); @@ -656,11 +650,6 @@ bool JReactNativeFeatureFlagsCxxInterop::enableDestroyShadowTreeRevisionAsync( return ReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync(); } -bool JReactNativeFeatureFlagsCxxInterop::enableDifferentiatorMutationVectorPreallocation( - facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::enableDifferentiatorMutationVectorPreallocation(); -} - bool JReactNativeFeatureFlagsCxxInterop::enableDoubleMeasurementFixAndroid( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableDoubleMeasurementFixAndroid(); @@ -1093,9 +1082,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableDestroyShadowTreeRevisionAsync", JReactNativeFeatureFlagsCxxInterop::enableDestroyShadowTreeRevisionAsync), - makeNativeMethod( - "enableDifferentiatorMutationVectorPreallocation", - JReactNativeFeatureFlagsCxxInterop::enableDifferentiatorMutationVectorPreallocation), makeNativeMethod( "enableDoubleMeasurementFixAndroid", JReactNativeFeatureFlagsCxxInterop::enableDoubleMeasurementFixAndroid), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index ee17298bb295..dad24ba4b6f0 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -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<<746da63dcbec1bb165731e7380993659>> + * @generated SignedSource<<19ab9f9ec4e3470290f69e0803ade5d4>> */ /** @@ -81,9 +81,6 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableDestroyShadowTreeRevisionAsync( facebook::jni::alias_ref); - static bool enableDifferentiatorMutationVectorPreallocation( - facebook::jni::alias_ref); - static bool enableDoubleMeasurementFixAndroid( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index e0afab4aa719..a04c2178502c 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -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<<38e26847bb30888adaf6a965dae07cfb>> + * @generated SignedSource<> */ /** @@ -94,10 +94,6 @@ bool ReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync() { return getAccessor().enableDestroyShadowTreeRevisionAsync(); } -bool ReactNativeFeatureFlags::enableDifferentiatorMutationVectorPreallocation() { - return getAccessor().enableDifferentiatorMutationVectorPreallocation(); -} - bool ReactNativeFeatureFlags::enableDoubleMeasurementFixAndroid() { return getAccessor().enableDoubleMeasurementFixAndroid(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 1e167a5a44b5..b6380f836fc5 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -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<<6958847f0d788c06cf64478ee2c36386>> + * @generated SignedSource<<9180537aa2031cfcbab5ffbdf1dc32d1>> */ /** @@ -124,11 +124,6 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableDestroyShadowTreeRevisionAsync(); - /** - * Pre-allocate mutation vectors in the Differentiator to reduce reallocation overhead during shadow view diffing. - */ - RN_EXPORT static bool enableDifferentiatorMutationVectorPreallocation(); - /** * When enabled a subset of components will avoid double measurement on Android. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 0c001f924d8d..f56fe350a1af 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -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<<78640fe49801cfa03638739e712c5e92>> + * @generated SignedSource<<804a4710d98f97c94928b77ad2cab2f7>> */ /** @@ -335,24 +335,6 @@ bool ReactNativeFeatureFlagsAccessor::enableDestroyShadowTreeRevisionAsync() { return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::enableDifferentiatorMutationVectorPreallocation() { - auto flagValue = enableDifferentiatorMutationVectorPreallocation_.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(17, "enableDifferentiatorMutationVectorPreallocation"); - - flagValue = currentProvider_->enableDifferentiatorMutationVectorPreallocation(); - enableDifferentiatorMutationVectorPreallocation_ = flagValue; - } - - return flagValue.value(); -} - bool ReactNativeFeatureFlagsAccessor::enableDoubleMeasurementFixAndroid() { auto flagValue = enableDoubleMeasurementFixAndroid_.load(); @@ -362,7 +344,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDoubleMeasurementFixAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(18, "enableDoubleMeasurementFixAndroid"); + markFlagAsAccessed(17, "enableDoubleMeasurementFixAndroid"); flagValue = currentProvider_->enableDoubleMeasurementFixAndroid(); enableDoubleMeasurementFixAndroid_ = flagValue; @@ -380,7 +362,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(19, "enableEagerRootViewAttachment"); + markFlagAsAccessed(18, "enableEagerRootViewAttachment"); flagValue = currentProvider_->enableEagerRootViewAttachment(); enableEagerRootViewAttachment_ = flagValue; @@ -398,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::enableExclusivePropsUpdateAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "enableExclusivePropsUpdateAndroid"); + markFlagAsAccessed(19, "enableExclusivePropsUpdateAndroid"); flagValue = currentProvider_->enableExclusivePropsUpdateAndroid(); enableExclusivePropsUpdateAndroid_ = flagValue; @@ -416,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricCommitBranching() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "enableFabricCommitBranching"); + markFlagAsAccessed(20, "enableFabricCommitBranching"); flagValue = currentProvider_->enableFabricCommitBranching(); enableFabricCommitBranching_ = flagValue; @@ -434,7 +416,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(22, "enableFabricLogs"); + markFlagAsAccessed(21, "enableFabricLogs"); flagValue = currentProvider_->enableFabricLogs(); enableFabricLogs_ = flagValue; @@ -452,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFlexboxAutoMinSizeInStrictMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(23, "enableFlexboxAutoMinSizeInStrictMode"); + markFlagAsAccessed(22, "enableFlexboxAutoMinSizeInStrictMode"); flagValue = currentProvider_->enableFlexboxAutoMinSizeInStrictMode(); enableFlexboxAutoMinSizeInStrictMode_ = flagValue; @@ -470,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFontScaleChangesUpdatingLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableFontScaleChangesUpdatingLayout"); + markFlagAsAccessed(23, "enableFontScaleChangesUpdatingLayout"); flagValue = currentProvider_->enableFontScaleChangesUpdatingLayout(); enableFontScaleChangesUpdatingLayout_ = flagValue; @@ -488,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSTextBaselineOffsetPerLine() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "enableIOSTextBaselineOffsetPerLine"); + markFlagAsAccessed(24, "enableIOSTextBaselineOffsetPerLine"); flagValue = currentProvider_->enableIOSTextBaselineOffsetPerLine(); enableIOSTextBaselineOffsetPerLine_ = flagValue; @@ -506,7 +488,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(26, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(25, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -524,7 +506,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(27, "enableImagePrefetchingAndroid"); + markFlagAsAccessed(26, "enableImagePrefetchingAndroid"); flagValue = currentProvider_->enableImagePrefetchingAndroid(); enableImagePrefetchingAndroid_ = flagValue; @@ -542,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImageRequestDowngradingForNonVisible // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "enableImageRequestDowngradingForNonVisibleImages"); + markFlagAsAccessed(27, "enableImageRequestDowngradingForNonVisibleImages"); flagValue = currentProvider_->enableImageRequestDowngradingForNonVisibleImages(); enableImageRequestDowngradingForNonVisibleImages_ = flagValue; @@ -560,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetC // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "enableImmediateUpdateModeForContentOffsetChanges"); + markFlagAsAccessed(28, "enableImmediateUpdateModeForContentOffsetChanges"); flagValue = currentProvider_->enableImmediateUpdateModeForContentOffsetChanges(); enableImmediateUpdateModeForContentOffsetChanges_ = flagValue; @@ -578,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImperativeFocus() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "enableImperativeFocus"); + markFlagAsAccessed(29, "enableImperativeFocus"); flagValue = currentProvider_->enableImperativeFocus(); enableImperativeFocus_ = flagValue; @@ -596,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::enableInteropViewManagerClassLookUpOptimiz // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "enableInteropViewManagerClassLookUpOptimizationIOS"); + markFlagAsAccessed(30, "enableInteropViewManagerClassLookUpOptimizationIOS"); flagValue = currentProvider_->enableInteropViewManagerClassLookUpOptimizationIOS(); enableInteropViewManagerClassLookUpOptimizationIOS_ = flagValue; @@ -614,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIntersectionObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "enableIntersectionObserverByDefault"); + markFlagAsAccessed(31, "enableIntersectionObserverByDefault"); flagValue = currentProvider_->enableIntersectionObserverByDefault(); enableIntersectionObserverByDefault_ = flagValue; @@ -632,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::enableKeyEvents() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "enableKeyEvents"); + markFlagAsAccessed(32, "enableKeyEvents"); flagValue = currentProvider_->enableKeyEvents(); enableKeyEvents_ = flagValue; @@ -650,7 +632,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(34, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(33, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -668,7 +650,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(35, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(34, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -686,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::enableModuleArgumentNSNullConversionIOS() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "enableModuleArgumentNSNullConversionIOS"); + markFlagAsAccessed(35, "enableModuleArgumentNSNullConversionIOS"); flagValue = currentProvider_->enableModuleArgumentNSNullConversionIOS(); enableModuleArgumentNSNullConversionIOS_ = flagValue; @@ -704,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMutationObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "enableMutationObserverByDefault"); + markFlagAsAccessed(36, "enableMutationObserverByDefault"); flagValue = currentProvider_->enableMutationObserverByDefault(); enableMutationObserverByDefault_ = flagValue; @@ -722,7 +704,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(38, "enableNativeCSSParsing"); + markFlagAsAccessed(37, "enableNativeCSSParsing"); flagValue = currentProvider_->enableNativeCSSParsing(); enableNativeCSSParsing_ = flagValue; @@ -740,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNetworkEventReporting() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "enableNetworkEventReporting"); + markFlagAsAccessed(38, "enableNetworkEventReporting"); flagValue = currentProvider_->enableNetworkEventReporting(); enableNetworkEventReporting_ = flagValue; @@ -758,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreparedTextLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "enablePreparedTextLayout"); + markFlagAsAccessed(39, "enablePreparedTextLayout"); flagValue = currentProvider_->enablePreparedTextLayout(); enablePreparedTextLayout_ = flagValue; @@ -776,7 +758,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(41, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(40, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -794,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::enableRuntimeSchedulerQueueClearingOnError // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "enableRuntimeSchedulerQueueClearingOnError"); + markFlagAsAccessed(41, "enableRuntimeSchedulerQueueClearingOnError"); flagValue = currentProvider_->enableRuntimeSchedulerQueueClearingOnError(); enableRuntimeSchedulerQueueClearingOnError_ = flagValue; @@ -812,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSchedulerDelegateInvalidation() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "enableSchedulerDelegateInvalidation"); + markFlagAsAccessed(42, "enableSchedulerDelegateInvalidation"); flagValue = currentProvider_->enableSchedulerDelegateInvalidation(); enableSchedulerDelegateInvalidation_ = flagValue; @@ -830,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSwiftUIBasedFilters() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "enableSwiftUIBasedFilters"); + markFlagAsAccessed(43, "enableSwiftUIBasedFilters"); flagValue = currentProvider_->enableSwiftUIBasedFilters(); enableSwiftUIBasedFilters_ = flagValue; @@ -848,7 +830,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(45, "enableViewCulling"); + markFlagAsAccessed(44, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -866,7 +848,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(46, "enableViewRecycling"); + markFlagAsAccessed(45, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -884,7 +866,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForImage() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "enableViewRecyclingForImage"); + markFlagAsAccessed(46, "enableViewRecyclingForImage"); flagValue = currentProvider_->enableViewRecyclingForImage(); enableViewRecyclingForImage_ = flagValue; @@ -902,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForScrollView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(48, "enableViewRecyclingForScrollView"); + markFlagAsAccessed(47, "enableViewRecyclingForScrollView"); flagValue = currentProvider_->enableViewRecyclingForScrollView(); enableViewRecyclingForScrollView_ = flagValue; @@ -920,7 +902,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(49, "enableViewRecyclingForText"); + markFlagAsAccessed(48, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -938,7 +920,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(50, "enableViewRecyclingForView"); + markFlagAsAccessed(49, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -956,7 +938,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewContainerStateExperimenta // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(51, "enableVirtualViewContainerStateExperimental"); + markFlagAsAccessed(50, "enableVirtualViewContainerStateExperimental"); flagValue = currentProvider_->enableVirtualViewContainerStateExperimental(); enableVirtualViewContainerStateExperimental_ = flagValue; @@ -974,7 +956,7 @@ bool ReactNativeFeatureFlagsAccessor::fixDifferentiatorParentTagForUnflattenCase // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(52, "fixDifferentiatorParentTagForUnflattenCase"); + markFlagAsAccessed(51, "fixDifferentiatorParentTagForUnflattenCase"); flagValue = currentProvider_->fixDifferentiatorParentTagForUnflattenCase(); fixDifferentiatorParentTagForUnflattenCase_ = flagValue; @@ -992,7 +974,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(53, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(52, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -1010,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::fixYogaFlexBasisFitContentInMainAxis() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(54, "fixYogaFlexBasisFitContentInMainAxis"); + markFlagAsAccessed(53, "fixYogaFlexBasisFitContentInMainAxis"); flagValue = currentProvider_->fixYogaFlexBasisFitContentInMainAxis(); fixYogaFlexBasisFitContentInMainAxis_ = flagValue; @@ -1028,7 +1010,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxAssertSingleHostState() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(55, "fuseboxAssertSingleHostState"); + markFlagAsAccessed(54, "fuseboxAssertSingleHostState"); flagValue = currentProvider_->fuseboxAssertSingleHostState(); fuseboxAssertSingleHostState_ = flagValue; @@ -1046,7 +1028,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(56, "fuseboxEnabledRelease"); + markFlagAsAccessed(55, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -1064,7 +1046,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxFrameRecordingEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(57, "fuseboxFrameRecordingEnabled"); + markFlagAsAccessed(56, "fuseboxFrameRecordingEnabled"); flagValue = currentProvider_->fuseboxFrameRecordingEnabled(); fuseboxFrameRecordingEnabled_ = flagValue; @@ -1082,7 +1064,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(58, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(57, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -1100,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxScreenshotCaptureEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(59, "fuseboxScreenshotCaptureEnabled"); + markFlagAsAccessed(58, "fuseboxScreenshotCaptureEnabled"); flagValue = currentProvider_->fuseboxScreenshotCaptureEnabled(); fuseboxScreenshotCaptureEnabled_ = flagValue; @@ -1118,7 +1100,7 @@ bool ReactNativeFeatureFlagsAccessor::hideOffscreenVirtualViewsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(60, "hideOffscreenVirtualViewsOnIOS"); + markFlagAsAccessed(59, "hideOffscreenVirtualViewsOnIOS"); flagValue = currentProvider_->hideOffscreenVirtualViewsOnIOS(); hideOffscreenVirtualViewsOnIOS_ = flagValue; @@ -1136,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::optimizedAnimatedPropUpdates() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(61, "optimizedAnimatedPropUpdates"); + markFlagAsAccessed(60, "optimizedAnimatedPropUpdates"); flagValue = currentProvider_->optimizedAnimatedPropUpdates(); optimizedAnimatedPropUpdates_ = flagValue; @@ -1154,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::overrideBySynchronousMountPropsAtMountingA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(62, "overrideBySynchronousMountPropsAtMountingAndroid"); + markFlagAsAccessed(61, "overrideBySynchronousMountPropsAtMountingAndroid"); flagValue = currentProvider_->overrideBySynchronousMountPropsAtMountingAndroid(); overrideBySynchronousMountPropsAtMountingAndroid_ = flagValue; @@ -1172,7 +1154,7 @@ bool ReactNativeFeatureFlagsAccessor::perfIssuesEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(63, "perfIssuesEnabled"); + markFlagAsAccessed(62, "perfIssuesEnabled"); flagValue = currentProvider_->perfIssuesEnabled(); perfIssuesEnabled_ = flagValue; @@ -1190,7 +1172,7 @@ bool ReactNativeFeatureFlagsAccessor::perfMonitorV2Enabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(64, "perfMonitorV2Enabled"); + markFlagAsAccessed(63, "perfMonitorV2Enabled"); flagValue = currentProvider_->perfMonitorV2Enabled(); perfMonitorV2Enabled_ = flagValue; @@ -1208,7 +1190,7 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(65, "preparedTextCacheSize"); + markFlagAsAccessed(64, "preparedTextCacheSize"); flagValue = currentProvider_->preparedTextCacheSize(); preparedTextCacheSize_ = flagValue; @@ -1226,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(66, "preventShadowTreeCommitExhaustion"); + markFlagAsAccessed(65, "preventShadowTreeCommitExhaustion"); flagValue = currentProvider_->preventShadowTreeCommitExhaustion(); preventShadowTreeCommitExhaustion_ = flagValue; @@ -1244,7 +1226,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2Android() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(67, "redBoxV2Android"); + markFlagAsAccessed(66, "redBoxV2Android"); flagValue = currentProvider_->redBoxV2Android(); redBoxV2Android_ = flagValue; @@ -1262,7 +1244,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2IOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(68, "redBoxV2IOS"); + markFlagAsAccessed(67, "redBoxV2IOS"); flagValue = currentProvider_->redBoxV2IOS(); redBoxV2IOS_ = flagValue; @@ -1280,7 +1262,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(69, "shouldPressibilityUseW3CPointerEventsForHover"); + markFlagAsAccessed(68, "shouldPressibilityUseW3CPointerEventsForHover"); flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover(); shouldPressibilityUseW3CPointerEventsForHover_ = flagValue; @@ -1298,7 +1280,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldTriggerResponderTransferOnScrollAndr // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(70, "shouldTriggerResponderTransferOnScrollAndroid"); + markFlagAsAccessed(69, "shouldTriggerResponderTransferOnScrollAndroid"); flagValue = currentProvider_->shouldTriggerResponderTransferOnScrollAndroid(); shouldTriggerResponderTransferOnScrollAndroid_ = flagValue; @@ -1316,7 +1298,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(71, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(70, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -1334,7 +1316,7 @@ bool ReactNativeFeatureFlagsAccessor::syncAndroidClipBoundsWithOverflow() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(72, "syncAndroidClipBoundsWithOverflow"); + markFlagAsAccessed(71, "syncAndroidClipBoundsWithOverflow"); flagValue = currentProvider_->syncAndroidClipBoundsWithOverflow(); syncAndroidClipBoundsWithOverflow_ = flagValue; @@ -1352,7 +1334,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(73, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(72, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -1370,7 +1352,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(74, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(73, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -1388,7 +1370,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommitT // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(75, "updateRuntimeShadowNodeReferencesOnCommitThread"); + markFlagAsAccessed(74, "updateRuntimeShadowNodeReferencesOnCommitThread"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommitThread(); updateRuntimeShadowNodeReferencesOnCommitThread_ = flagValue; @@ -1406,7 +1388,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(76, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(75, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1424,7 +1406,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(77, "useFabricInterop"); + markFlagAsAccessed(76, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1442,7 +1424,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(78, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(77, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1460,7 +1442,7 @@ bool ReactNativeFeatureFlagsAccessor::useNestedScrollViewAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(79, "useNestedScrollViewAndroid"); + markFlagAsAccessed(78, "useNestedScrollViewAndroid"); flagValue = currentProvider_->useNestedScrollViewAndroid(); useNestedScrollViewAndroid_ = flagValue; @@ -1478,7 +1460,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedViewRegistryOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(80, "useOptimizedViewRegistryOnAndroid"); + markFlagAsAccessed(79, "useOptimizedViewRegistryOnAndroid"); flagValue = currentProvider_->useOptimizedViewRegistryOnAndroid(); useOptimizedViewRegistryOnAndroid_ = flagValue; @@ -1496,7 +1478,7 @@ bool ReactNativeFeatureFlagsAccessor::useSharedAnimatedBackend() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(81, "useSharedAnimatedBackend"); + markFlagAsAccessed(80, "useSharedAnimatedBackend"); flagValue = currentProvider_->useSharedAnimatedBackend(); useSharedAnimatedBackend_ = flagValue; @@ -1514,7 +1496,7 @@ bool ReactNativeFeatureFlagsAccessor::useTraitHiddenOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(82, "useTraitHiddenOnAndroid"); + markFlagAsAccessed(81, "useTraitHiddenOnAndroid"); flagValue = currentProvider_->useTraitHiddenOnAndroid(); useTraitHiddenOnAndroid_ = flagValue; @@ -1532,7 +1514,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(83, "useTurboModuleInterop"); + markFlagAsAccessed(82, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1550,7 +1532,7 @@ double ReactNativeFeatureFlagsAccessor::viewCullingOutsetRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(84, "viewCullingOutsetRatio"); + markFlagAsAccessed(83, "viewCullingOutsetRatio"); flagValue = currentProvider_->viewCullingOutsetRatio(); viewCullingOutsetRatio_ = flagValue; @@ -1568,7 +1550,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(85, "viewTransitionEnabled"); + markFlagAsAccessed(84, "viewTransitionEnabled"); flagValue = currentProvider_->viewTransitionEnabled(); viewTransitionEnabled_ = flagValue; @@ -1586,7 +1568,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionUseHardwareBitmapAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(86, "viewTransitionUseHardwareBitmapAndroid"); + markFlagAsAccessed(85, "viewTransitionUseHardwareBitmapAndroid"); flagValue = currentProvider_->viewTransitionUseHardwareBitmapAndroid(); viewTransitionUseHardwareBitmapAndroid_ = flagValue; @@ -1604,7 +1586,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(87, "virtualViewPrerenderRatio"); + markFlagAsAccessed(86, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 3bd3cb987fb1..dfadab456759 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -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<<1974d5797f43e8f73b521ebfd46ce492>> + * @generated SignedSource<<05c5b9db2533ee81fb2f10149d2d6bd5>> */ /** @@ -49,7 +49,6 @@ class ReactNativeFeatureFlagsAccessor { bool enableCppPropsIteratorSetter(); bool enableCustomFocusSearchOnClippedElementsAndroid(); bool enableDestroyShadowTreeRevisionAsync(); - bool enableDifferentiatorMutationVectorPreallocation(); bool enableDoubleMeasurementFixAndroid(); bool enableEagerRootViewAttachment(); bool enableExclusivePropsUpdateAndroid(); @@ -131,7 +130,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 88> accessedFeatureFlags_; + std::array, 87> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -150,7 +149,6 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableCppPropsIteratorSetter_; std::atomic> enableCustomFocusSearchOnClippedElementsAndroid_; std::atomic> enableDestroyShadowTreeRevisionAsync_; - std::atomic> enableDifferentiatorMutationVectorPreallocation_; std::atomic> enableDoubleMeasurementFixAndroid_; std::atomic> enableEagerRootViewAttachment_; std::atomic> enableExclusivePropsUpdateAndroid_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index e6819ac0f5be..e7f8c648ee6c 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -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<> + * @generated SignedSource<> */ /** @@ -95,10 +95,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } - bool enableDifferentiatorMutationVectorPreallocation() override { - return false; - } - bool enableDoubleMeasurementFixAndroid() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index fcfa1eff96a5..197fc0bbaf93 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -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<<15bb8c904ef3116d0f6042623a150d8c>> + * @generated SignedSource<> */ /** @@ -198,15 +198,6 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::enableDestroyShadowTreeRevisionAsync(); } - bool enableDifferentiatorMutationVectorPreallocation() override { - auto value = values_["enableDifferentiatorMutationVectorPreallocation"]; - if (!value.isNull()) { - return value.getBool(); - } - - return ReactNativeFeatureFlagsDefaults::enableDifferentiatorMutationVectorPreallocation(); - } - bool enableDoubleMeasurementFixAndroid() override { auto value = values_["enableDoubleMeasurementFixAndroid"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index f3781b150a1c..6f9bbe9fbcdc 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -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<> + * @generated SignedSource<> */ /** @@ -42,7 +42,6 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableCppPropsIteratorSetter() = 0; virtual bool enableCustomFocusSearchOnClippedElementsAndroid() = 0; virtual bool enableDestroyShadowTreeRevisionAsync() = 0; - virtual bool enableDifferentiatorMutationVectorPreallocation() = 0; virtual bool enableDoubleMeasurementFixAndroid() = 0; virtual bool enableEagerRootViewAttachment() = 0; virtual bool enableExclusivePropsUpdateAndroid() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 06f80646d7ae..a284d170b65b 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -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<<34ba54f5915738fc4792567680679880>> + * @generated SignedSource<> */ /** @@ -129,11 +129,6 @@ bool NativeReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync( return ReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync(); } -bool NativeReactNativeFeatureFlags::enableDifferentiatorMutationVectorPreallocation( - jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::enableDifferentiatorMutationVectorPreallocation(); -} - bool NativeReactNativeFeatureFlags::enableDoubleMeasurementFixAndroid( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableDoubleMeasurementFixAndroid(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 033fa3999427..a1e5738db75a 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -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<<32404575231774f230ece7a097ae08c5>> + * @generated SignedSource<<73dbb47c8b78009dd8212c19adf51dc0>> */ /** @@ -70,8 +70,6 @@ class NativeReactNativeFeatureFlags bool enableDestroyShadowTreeRevisionAsync(jsi::Runtime& runtime); - bool enableDifferentiatorMutationVectorPreallocation(jsi::Runtime& runtime); - bool enableDoubleMeasurementFixAndroid(jsi::Runtime& runtime); bool enableEagerRootViewAttachment(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp index dd89fbb89a33..3e1307093315 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp @@ -892,20 +892,6 @@ static void calculateShadowViewMutations( // Lists of mutations auto mutationContainer = OrderedMutationInstructionContainer{}; - if (ReactNativeFeatureFlags:: - enableDifferentiatorMutationVectorPreallocation()) { - // Pre-allocate mutation sub-vectors based on expected child count to avoid - // repeated reallocations during diffing. - size_t estimatedSize = std::max(oldChildPairs.size(), newChildPairs.size()); - mutationContainer.createMutations.reserve(estimatedSize); - mutationContainer.deleteMutations.reserve(estimatedSize); - mutationContainer.insertMutations.reserve(estimatedSize); - mutationContainer.removeMutations.reserve(estimatedSize); - mutationContainer.updateMutations.reserve(estimatedSize); - mutationContainer.downwardMutations.reserve(estimatedSize); - mutationContainer.destructiveDownwardMutations.reserve(estimatedSize); - } - DEBUG_LOGS({ LOG(ERROR) << "Differ Entry: Child Pairs of node: [" << parentTag << "]"; LOG(ERROR) << "> Old Child Pairs: " << oldChildPairs; @@ -1339,19 +1325,6 @@ static void calculateShadowViewMutations( } } - if (ReactNativeFeatureFlags:: - enableDifferentiatorMutationVectorPreallocation()) { - mutations.reserve( - mutations.size() + - mutationContainer.destructiveDownwardMutations.size() + - mutationContainer.updateMutations.size() + - mutationContainer.removeMutations.size() + - mutationContainer.deleteMutations.size() + - mutationContainer.createMutations.size() + - mutationContainer.downwardMutations.size() + - mutationContainer.insertMutations.size()); - } - // All mutations in an optimal order: std::move( mutationContainer.destructiveDownwardMutations.begin(), @@ -1420,14 +1393,7 @@ ShadowViewMutation::List calculateShadowViewMutations( {} /* layoutOffset */, {} /* cullingContext */); - if (ReactNativeFeatureFlags:: - enableDifferentiatorMutationVectorPreallocation()) { - // Estimate ~2 mutations per view (create + insert or remove + delete). - mutations.reserve( - std::max(size_t(256), (sliceOne.size() + sliceTwo.size()) * 2)); - } else { - mutations.reserve(256); - } + mutations.reserve(256); calculateShadowViewMutations( innerViewNodePairScope, diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index d8e33fe817e4..23afd9eee8da 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -232,17 +232,6 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, - enableDifferentiatorMutationVectorPreallocation: { - defaultValue: false, - metadata: { - dateAdded: '2026-02-28', - description: - 'Pre-allocate mutation vectors in the Differentiator to reduce reallocation overhead during shadow view diffing.', - expectedReleaseValue: true, - purpose: 'experimentation', - }, - ossReleaseStage: 'none', - }, enableDoubleMeasurementFixAndroid: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index d1a25226a318..8fc394e3eadb 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -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<<3304b4ee2c718dbf4d56b607ea09054d>> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -66,7 +66,6 @@ export type ReactNativeFeatureFlags = Readonly<{ enableCppPropsIteratorSetter: Getter, enableCustomFocusSearchOnClippedElementsAndroid: Getter, enableDestroyShadowTreeRevisionAsync: Getter, - enableDifferentiatorMutationVectorPreallocation: Getter, enableDoubleMeasurementFixAndroid: Getter, enableEagerRootViewAttachment: Getter, enableExclusivePropsUpdateAndroid: Getter, @@ -281,10 +280,6 @@ export const enableCustomFocusSearchOnClippedElementsAndroid: Getter = * Enables destructor calls for ShadowTreeRevision in the background to reduce UI thread work. */ export const enableDestroyShadowTreeRevisionAsync: Getter = createNativeFlagGetter('enableDestroyShadowTreeRevisionAsync', false); -/** - * Pre-allocate mutation vectors in the Differentiator to reduce reallocation overhead during shadow view diffing. - */ -export const enableDifferentiatorMutationVectorPreallocation: Getter = createNativeFlagGetter('enableDifferentiatorMutationVectorPreallocation', false); /** * When enabled a subset of components will avoid double measurement on Android. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index d6ec14c24655..40cae550b5ca 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -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<<7dce2cc7ad3dc4f61ba9ae24fcefe3c2>> + * @generated SignedSource<<7b1756a74caa546933eebb934d27de12>> * @flow strict * @noformat */ @@ -42,7 +42,6 @@ export interface Spec extends TurboModule { readonly enableCppPropsIteratorSetter?: () => boolean; readonly enableCustomFocusSearchOnClippedElementsAndroid?: () => boolean; readonly enableDestroyShadowTreeRevisionAsync?: () => boolean; - readonly enableDifferentiatorMutationVectorPreallocation?: () => boolean; readonly enableDoubleMeasurementFixAndroid?: () => boolean; readonly enableEagerRootViewAttachment?: () => boolean; readonly enableExclusivePropsUpdateAndroid?: () => boolean; From 3233436177c3880490c045756f8b63b0eaa2f7de Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Tue, 16 Jun 2026 07:26:44 -0700 Subject: [PATCH 006/561] Remove hideOffscreenVirtualViewsOnIOS feature flag (#57225) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57225 The `hideOffscreenVirtualViewsOnIOS` flag gated hiding of offscreen `VirtualView`s on iOS (setting `self.hidden`) in `RCTVirtualViewComponentView`. It was never ramped and is being removed. The flag defaulted to `false`, so the gated branches never set `hidden`; deleting them restores the pre-flag behavior. The now-unused `ReactNativeFeatureFlags.h` import is also removed. Removes the flag definition from `ReactNativeFeatureFlags.config.js`, the gated call sites in `RCTVirtualViewComponentView.mm`, and the regenerated feature-flag files (via `yarn featureflags --update`). Changelog: [Internal] Reviewed By: javache Differential Revision: D108411518 fbshipit-source-id: 50c5e6558b00c281bf143f780f6a029c9c876a18 --- .../RCTVirtualViewComponentView.mm | 18 ----- .../featureflags/ReactNativeFeatureFlags.kt | 8 +- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +-- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 +--- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 +--- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +- .../featureflags/ReactNativeFeatureFlags.h | 7 +- .../ReactNativeFeatureFlagsAccessor.cpp | 74 +++++++------------ .../ReactNativeFeatureFlagsAccessor.h | 6 +- .../ReactNativeFeatureFlagsDefaults.h | 6 +- .../ReactNativeFeatureFlagsDynamicProvider.h | 11 +-- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +- .../NativeReactNativeFeatureFlags.h | 4 +- .../ReactNativeFeatureFlags.config.js | 11 --- .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 21 files changed, 47 insertions(+), 182 deletions(-) diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/VirtualView/RCTVirtualViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/VirtualView/RCTVirtualViewComponentView.mm index f2383df8613f..7ced2e932d92 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/VirtualView/RCTVirtualViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/VirtualView/RCTVirtualViewComponentView.mm @@ -16,7 +16,6 @@ #import #import -#import #import #import #import @@ -65,9 +64,6 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared & if (!_mode.has_value()) { _mode = newViewProps.initialHidden ? RCTVirtualViewModeHidden : RCTVirtualViewModeVisible; - if (ReactNativeFeatureFlags::hideOffscreenVirtualViewsOnIOS()) { - self.hidden = newViewProps.initialHidden && !sIsAccessibilityUsed; - } } switch (newViewProps.renderState) { @@ -211,20 +207,6 @@ - (void)onModeChange:(RCTVirtualViewMode)newMode targetRect:(CGRect)targetRect t [self _dispatchAsyncModeChange:event]; break; } - - if (ReactNativeFeatureFlags::hideOffscreenVirtualViewsOnIOS()) { - switch (newMode) { - case RCTVirtualViewModeVisible: - self.hidden = NO; - break; - case RCTVirtualViewModePrerender: - self.hidden = !sIsAccessibilityUsed; - break; - case RCTVirtualViewModeHidden: - self.hidden = YES; - break; - } - } } #pragma mark - Private API diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 7e98a407ee76..dc61e2a20f39 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -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<<5307fff9429956a3f3f2f54f2b6b00e7>> + * @generated SignedSource<<17567d3adfba54ec2f888b50dae9efb8>> */ /** @@ -384,12 +384,6 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun fuseboxScreenshotCaptureEnabled(): Boolean = accessor.fuseboxScreenshotCaptureEnabled() - /** - * Hides offscreen VirtualViews on iOS by setting hidden = YES to avoid extra cost of views - */ - @JvmStatic - public fun hideOffscreenVirtualViewsOnIOS(): Boolean = accessor.hideOffscreenVirtualViewsOnIOS() - /** * When enabled, uses optimized platform-specific paths to apply animated props synchronously. On Android, this uses a batched int/double buffer protocol with a single JNI call. On iOS, this passes AnimatedProps directly through the delegate chain and applies them via cloneProps, avoiding the folly::dynamic round-trip. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index d43113255e58..7f003892085f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -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<> + * @generated SignedSource<<337b652caa9d443c8d83915e22210198>> */ /** @@ -79,7 +79,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var fuseboxFrameRecordingEnabledCache: Boolean? = null private var fuseboxNetworkInspectionEnabledCache: Boolean? = null private var fuseboxScreenshotCaptureEnabledCache: Boolean? = null - private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null private var optimizedAnimatedPropUpdatesCache: Boolean? = null private var overrideBySynchronousMountPropsAtMountingAndroidCache: Boolean? = null private var perfIssuesEnabledCache: Boolean? = null @@ -639,15 +638,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun hideOffscreenVirtualViewsOnIOS(): Boolean { - var cached = hideOffscreenVirtualViewsOnIOSCache - if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.hideOffscreenVirtualViewsOnIOS() - hideOffscreenVirtualViewsOnIOSCache = cached - } - return cached - } - override fun optimizedAnimatedPropUpdates(): Boolean { var cached = optimizedAnimatedPropUpdatesCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index ce4b7dd3519e..98bf3882ee23 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -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<<6dc403c11108a657d48ec9573bee842f>> + * @generated SignedSource<> */ /** @@ -146,8 +146,6 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun fuseboxScreenshotCaptureEnabled(): Boolean - @DoNotStrip @JvmStatic public external fun hideOffscreenVirtualViewsOnIOS(): Boolean - @DoNotStrip @JvmStatic public external fun optimizedAnimatedPropUpdates(): Boolean @DoNotStrip @JvmStatic public external fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index f90a51659f0f..4732a92c631b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -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<<452edce222866440ff3794deb178a7f4>> + * @generated SignedSource<> */ /** @@ -141,8 +141,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun fuseboxScreenshotCaptureEnabled(): Boolean = false - override fun hideOffscreenVirtualViewsOnIOS(): Boolean = false - override fun optimizedAnimatedPropUpdates(): Boolean = false override fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean = true diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index a2fd49e4990e..23633e4d7536 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -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<<8ba7f19e8afe329937b1b36d3b83dbc5>> + * @generated SignedSource<<164c9c2751f660ee098c12b8cf2c8b66>> */ /** @@ -83,7 +83,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var fuseboxFrameRecordingEnabledCache: Boolean? = null private var fuseboxNetworkInspectionEnabledCache: Boolean? = null private var fuseboxScreenshotCaptureEnabledCache: Boolean? = null - private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null private var optimizedAnimatedPropUpdatesCache: Boolean? = null private var overrideBySynchronousMountPropsAtMountingAndroidCache: Boolean? = null private var perfIssuesEnabledCache: Boolean? = null @@ -702,16 +701,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } - override fun hideOffscreenVirtualViewsOnIOS(): Boolean { - var cached = hideOffscreenVirtualViewsOnIOSCache - if (cached == null) { - cached = currentProvider.hideOffscreenVirtualViewsOnIOS() - accessedFeatureFlags.add("hideOffscreenVirtualViewsOnIOS") - hideOffscreenVirtualViewsOnIOSCache = cached - } - return cached - } - override fun optimizedAnimatedPropUpdates(): Boolean { var cached = optimizedAnimatedPropUpdatesCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 9402aed64871..50460e763de9 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -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<<3a3f9014f644b6b964b50d0974a7b9b5>> + * @generated SignedSource<> */ /** @@ -141,8 +141,6 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun fuseboxScreenshotCaptureEnabled(): Boolean - @DoNotStrip public fun hideOffscreenVirtualViewsOnIOS(): Boolean - @DoNotStrip public fun optimizedAnimatedPropUpdates(): Boolean @DoNotStrip public fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 96c8d0d17419..04c199adaf00 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -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<<70e4f4b4bb3aa28a644ede80ceeb4fc3>> + * @generated SignedSource<> */ /** @@ -393,12 +393,6 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } - bool hideOffscreenVirtualViewsOnIOS() override { - static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("hideOffscreenVirtualViewsOnIOS"); - return method(javaProvider_); - } - bool optimizedAnimatedPropUpdates() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("optimizedAnimatedPropUpdates"); @@ -860,11 +854,6 @@ bool JReactNativeFeatureFlagsCxxInterop::fuseboxScreenshotCaptureEnabled( return ReactNativeFeatureFlags::fuseboxScreenshotCaptureEnabled(); } -bool JReactNativeFeatureFlagsCxxInterop::hideOffscreenVirtualViewsOnIOS( - facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::hideOffscreenVirtualViewsOnIOS(); -} - bool JReactNativeFeatureFlagsCxxInterop::optimizedAnimatedPropUpdates( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::optimizedAnimatedPropUpdates(); @@ -1208,9 +1197,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "fuseboxScreenshotCaptureEnabled", JReactNativeFeatureFlagsCxxInterop::fuseboxScreenshotCaptureEnabled), - makeNativeMethod( - "hideOffscreenVirtualViewsOnIOS", - JReactNativeFeatureFlagsCxxInterop::hideOffscreenVirtualViewsOnIOS), makeNativeMethod( "optimizedAnimatedPropUpdates", JReactNativeFeatureFlagsCxxInterop::optimizedAnimatedPropUpdates), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index dad24ba4b6f0..591be913bf2d 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -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<<19ab9f9ec4e3470290f69e0803ade5d4>> + * @generated SignedSource<> */ /** @@ -207,9 +207,6 @@ class JReactNativeFeatureFlagsCxxInterop static bool fuseboxScreenshotCaptureEnabled( facebook::jni::alias_ref); - static bool hideOffscreenVirtualViewsOnIOS( - facebook::jni::alias_ref); - static bool optimizedAnimatedPropUpdates( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index a04c2178502c..78aefa5b9713 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -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<> + * @generated SignedSource<> */ /** @@ -262,10 +262,6 @@ bool ReactNativeFeatureFlags::fuseboxScreenshotCaptureEnabled() { return getAccessor().fuseboxScreenshotCaptureEnabled(); } -bool ReactNativeFeatureFlags::hideOffscreenVirtualViewsOnIOS() { - return getAccessor().hideOffscreenVirtualViewsOnIOS(); -} - bool ReactNativeFeatureFlags::optimizedAnimatedPropUpdates() { return getAccessor().optimizedAnimatedPropUpdates(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index b6380f836fc5..37e9094d1b41 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -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<<9180537aa2031cfcbab5ffbdf1dc32d1>> + * @generated SignedSource<> */ /** @@ -334,11 +334,6 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool fuseboxScreenshotCaptureEnabled(); - /** - * Hides offscreen VirtualViews on iOS by setting hidden = YES to avoid extra cost of views - */ - RN_EXPORT static bool hideOffscreenVirtualViewsOnIOS(); - /** * When enabled, uses optimized platform-specific paths to apply animated props synchronously. On Android, this uses a batched int/double buffer protocol with a single JNI call. On iOS, this passes AnimatedProps directly through the delegate chain and applies them via cloneProps, avoiding the folly::dynamic round-trip. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index f56fe350a1af..0a550efaf0e7 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -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<<804a4710d98f97c94928b77ad2cab2f7>> + * @generated SignedSource<<1c4a88ac3f4f2d04d2e9d986536df7d9>> */ /** @@ -1091,24 +1091,6 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxScreenshotCaptureEnabled() { return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::hideOffscreenVirtualViewsOnIOS() { - auto flagValue = hideOffscreenVirtualViewsOnIOS_.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(59, "hideOffscreenVirtualViewsOnIOS"); - - flagValue = currentProvider_->hideOffscreenVirtualViewsOnIOS(); - hideOffscreenVirtualViewsOnIOS_ = flagValue; - } - - return flagValue.value(); -} - bool ReactNativeFeatureFlagsAccessor::optimizedAnimatedPropUpdates() { auto flagValue = optimizedAnimatedPropUpdates_.load(); @@ -1118,7 +1100,7 @@ bool ReactNativeFeatureFlagsAccessor::optimizedAnimatedPropUpdates() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(60, "optimizedAnimatedPropUpdates"); + markFlagAsAccessed(59, "optimizedAnimatedPropUpdates"); flagValue = currentProvider_->optimizedAnimatedPropUpdates(); optimizedAnimatedPropUpdates_ = flagValue; @@ -1136,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::overrideBySynchronousMountPropsAtMountingA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(61, "overrideBySynchronousMountPropsAtMountingAndroid"); + markFlagAsAccessed(60, "overrideBySynchronousMountPropsAtMountingAndroid"); flagValue = currentProvider_->overrideBySynchronousMountPropsAtMountingAndroid(); overrideBySynchronousMountPropsAtMountingAndroid_ = flagValue; @@ -1154,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::perfIssuesEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(62, "perfIssuesEnabled"); + markFlagAsAccessed(61, "perfIssuesEnabled"); flagValue = currentProvider_->perfIssuesEnabled(); perfIssuesEnabled_ = flagValue; @@ -1172,7 +1154,7 @@ bool ReactNativeFeatureFlagsAccessor::perfMonitorV2Enabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(63, "perfMonitorV2Enabled"); + markFlagAsAccessed(62, "perfMonitorV2Enabled"); flagValue = currentProvider_->perfMonitorV2Enabled(); perfMonitorV2Enabled_ = flagValue; @@ -1190,7 +1172,7 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(64, "preparedTextCacheSize"); + markFlagAsAccessed(63, "preparedTextCacheSize"); flagValue = currentProvider_->preparedTextCacheSize(); preparedTextCacheSize_ = flagValue; @@ -1208,7 +1190,7 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(65, "preventShadowTreeCommitExhaustion"); + markFlagAsAccessed(64, "preventShadowTreeCommitExhaustion"); flagValue = currentProvider_->preventShadowTreeCommitExhaustion(); preventShadowTreeCommitExhaustion_ = flagValue; @@ -1226,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2Android() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(66, "redBoxV2Android"); + markFlagAsAccessed(65, "redBoxV2Android"); flagValue = currentProvider_->redBoxV2Android(); redBoxV2Android_ = flagValue; @@ -1244,7 +1226,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2IOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(67, "redBoxV2IOS"); + markFlagAsAccessed(66, "redBoxV2IOS"); flagValue = currentProvider_->redBoxV2IOS(); redBoxV2IOS_ = flagValue; @@ -1262,7 +1244,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(68, "shouldPressibilityUseW3CPointerEventsForHover"); + markFlagAsAccessed(67, "shouldPressibilityUseW3CPointerEventsForHover"); flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover(); shouldPressibilityUseW3CPointerEventsForHover_ = flagValue; @@ -1280,7 +1262,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldTriggerResponderTransferOnScrollAndr // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(69, "shouldTriggerResponderTransferOnScrollAndroid"); + markFlagAsAccessed(68, "shouldTriggerResponderTransferOnScrollAndroid"); flagValue = currentProvider_->shouldTriggerResponderTransferOnScrollAndroid(); shouldTriggerResponderTransferOnScrollAndroid_ = flagValue; @@ -1298,7 +1280,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(70, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(69, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -1316,7 +1298,7 @@ bool ReactNativeFeatureFlagsAccessor::syncAndroidClipBoundsWithOverflow() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(71, "syncAndroidClipBoundsWithOverflow"); + markFlagAsAccessed(70, "syncAndroidClipBoundsWithOverflow"); flagValue = currentProvider_->syncAndroidClipBoundsWithOverflow(); syncAndroidClipBoundsWithOverflow_ = flagValue; @@ -1334,7 +1316,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(72, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(71, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -1352,7 +1334,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(73, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(72, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -1370,7 +1352,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommitT // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(74, "updateRuntimeShadowNodeReferencesOnCommitThread"); + markFlagAsAccessed(73, "updateRuntimeShadowNodeReferencesOnCommitThread"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommitThread(); updateRuntimeShadowNodeReferencesOnCommitThread_ = flagValue; @@ -1388,7 +1370,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(75, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(74, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1406,7 +1388,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(76, "useFabricInterop"); + markFlagAsAccessed(75, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1424,7 +1406,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(77, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(76, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1442,7 +1424,7 @@ bool ReactNativeFeatureFlagsAccessor::useNestedScrollViewAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(78, "useNestedScrollViewAndroid"); + markFlagAsAccessed(77, "useNestedScrollViewAndroid"); flagValue = currentProvider_->useNestedScrollViewAndroid(); useNestedScrollViewAndroid_ = flagValue; @@ -1460,7 +1442,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedViewRegistryOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(79, "useOptimizedViewRegistryOnAndroid"); + markFlagAsAccessed(78, "useOptimizedViewRegistryOnAndroid"); flagValue = currentProvider_->useOptimizedViewRegistryOnAndroid(); useOptimizedViewRegistryOnAndroid_ = flagValue; @@ -1478,7 +1460,7 @@ bool ReactNativeFeatureFlagsAccessor::useSharedAnimatedBackend() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(80, "useSharedAnimatedBackend"); + markFlagAsAccessed(79, "useSharedAnimatedBackend"); flagValue = currentProvider_->useSharedAnimatedBackend(); useSharedAnimatedBackend_ = flagValue; @@ -1496,7 +1478,7 @@ bool ReactNativeFeatureFlagsAccessor::useTraitHiddenOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(81, "useTraitHiddenOnAndroid"); + markFlagAsAccessed(80, "useTraitHiddenOnAndroid"); flagValue = currentProvider_->useTraitHiddenOnAndroid(); useTraitHiddenOnAndroid_ = flagValue; @@ -1514,7 +1496,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(82, "useTurboModuleInterop"); + markFlagAsAccessed(81, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1532,7 +1514,7 @@ double ReactNativeFeatureFlagsAccessor::viewCullingOutsetRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(83, "viewCullingOutsetRatio"); + markFlagAsAccessed(82, "viewCullingOutsetRatio"); flagValue = currentProvider_->viewCullingOutsetRatio(); viewCullingOutsetRatio_ = flagValue; @@ -1550,7 +1532,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(84, "viewTransitionEnabled"); + markFlagAsAccessed(83, "viewTransitionEnabled"); flagValue = currentProvider_->viewTransitionEnabled(); viewTransitionEnabled_ = flagValue; @@ -1568,7 +1550,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionUseHardwareBitmapAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(85, "viewTransitionUseHardwareBitmapAndroid"); + markFlagAsAccessed(84, "viewTransitionUseHardwareBitmapAndroid"); flagValue = currentProvider_->viewTransitionUseHardwareBitmapAndroid(); viewTransitionUseHardwareBitmapAndroid_ = flagValue; @@ -1586,7 +1568,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(86, "virtualViewPrerenderRatio"); + markFlagAsAccessed(85, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index dfadab456759..10aec19ebdc0 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -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<<05c5b9db2533ee81fb2f10149d2d6bd5>> + * @generated SignedSource<<9961a0c8efe857161fb861f2873a3749>> */ /** @@ -91,7 +91,6 @@ class ReactNativeFeatureFlagsAccessor { bool fuseboxFrameRecordingEnabled(); bool fuseboxNetworkInspectionEnabled(); bool fuseboxScreenshotCaptureEnabled(); - bool hideOffscreenVirtualViewsOnIOS(); bool optimizedAnimatedPropUpdates(); bool overrideBySynchronousMountPropsAtMountingAndroid(); bool perfIssuesEnabled(); @@ -130,7 +129,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 87> accessedFeatureFlags_; + std::array, 86> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -191,7 +190,6 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> fuseboxFrameRecordingEnabled_; std::atomic> fuseboxNetworkInspectionEnabled_; std::atomic> fuseboxScreenshotCaptureEnabled_; - std::atomic> hideOffscreenVirtualViewsOnIOS_; std::atomic> optimizedAnimatedPropUpdates_; std::atomic> overrideBySynchronousMountPropsAtMountingAndroid_; std::atomic> perfIssuesEnabled_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index e7f8c648ee6c..d85cb77a016a 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -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<> + * @generated SignedSource<> */ /** @@ -263,10 +263,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } - bool hideOffscreenVirtualViewsOnIOS() override { - return false; - } - bool optimizedAnimatedPropUpdates() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 197fc0bbaf93..3558ac5a30a1 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -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<> + * @generated SignedSource<<6db86679458aa76ebb30082ba12a32ae>> */ /** @@ -576,15 +576,6 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::fuseboxScreenshotCaptureEnabled(); } - bool hideOffscreenVirtualViewsOnIOS() override { - auto value = values_["hideOffscreenVirtualViewsOnIOS"]; - if (!value.isNull()) { - return value.getBool(); - } - - return ReactNativeFeatureFlagsDefaults::hideOffscreenVirtualViewsOnIOS(); - } - bool optimizedAnimatedPropUpdates() override { auto value = values_["optimizedAnimatedPropUpdates"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 6f9bbe9fbcdc..956231ed0477 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -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<> + * @generated SignedSource<> */ /** @@ -84,7 +84,6 @@ class ReactNativeFeatureFlagsProvider { virtual bool fuseboxFrameRecordingEnabled() = 0; virtual bool fuseboxNetworkInspectionEnabled() = 0; virtual bool fuseboxScreenshotCaptureEnabled() = 0; - virtual bool hideOffscreenVirtualViewsOnIOS() = 0; virtual bool optimizedAnimatedPropUpdates() = 0; virtual bool overrideBySynchronousMountPropsAtMountingAndroid() = 0; virtual bool perfIssuesEnabled() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index a284d170b65b..83802a955650 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -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<> + * @generated SignedSource<> */ /** @@ -339,11 +339,6 @@ bool NativeReactNativeFeatureFlags::fuseboxScreenshotCaptureEnabled( return ReactNativeFeatureFlags::fuseboxScreenshotCaptureEnabled(); } -bool NativeReactNativeFeatureFlags::hideOffscreenVirtualViewsOnIOS( - jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::hideOffscreenVirtualViewsOnIOS(); -} - bool NativeReactNativeFeatureFlags::optimizedAnimatedPropUpdates( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::optimizedAnimatedPropUpdates(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index a1e5738db75a..e29d9ac03b8e 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -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<<73dbb47c8b78009dd8212c19adf51dc0>> + * @generated SignedSource<> */ /** @@ -154,8 +154,6 @@ class NativeReactNativeFeatureFlags bool fuseboxScreenshotCaptureEnabled(jsi::Runtime& runtime); - bool hideOffscreenVirtualViewsOnIOS(jsi::Runtime& runtime); - bool optimizedAnimatedPropUpdates(jsi::Runtime& runtime); bool overrideBySynchronousMountPropsAtMountingAndroid(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 23afd9eee8da..be1206256523 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -679,17 +679,6 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, - hideOffscreenVirtualViewsOnIOS: { - defaultValue: false, - metadata: { - dateAdded: '2025-06-30', - description: - 'Hides offscreen VirtualViews on iOS by setting hidden = YES to avoid extra cost of views', - expectedReleaseValue: true, - purpose: 'experimentation', - }, - ossReleaseStage: 'none', - }, optimizedAnimatedPropUpdates: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 8fc394e3eadb..b3b3f6a2eca2 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -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<> + * @generated SignedSource<<785d84f617e6b1870c3ff1eeed9f1c66>> * @flow strict * @noformat */ @@ -108,7 +108,6 @@ export type ReactNativeFeatureFlags = Readonly<{ fuseboxFrameRecordingEnabled: Getter, fuseboxNetworkInspectionEnabled: Getter, fuseboxScreenshotCaptureEnabled: Getter, - hideOffscreenVirtualViewsOnIOS: Getter, optimizedAnimatedPropUpdates: Getter, overrideBySynchronousMountPropsAtMountingAndroid: Getter, perfIssuesEnabled: Getter, @@ -448,10 +447,6 @@ export const fuseboxNetworkInspectionEnabled: Getter = createNativeFlag * Enable Page.captureScreenshot CDP method support in the React Native DevTools CDP backend. This flag is global and should not be changed across React Host lifetimes. */ export const fuseboxScreenshotCaptureEnabled: Getter = createNativeFlagGetter('fuseboxScreenshotCaptureEnabled', false); -/** - * Hides offscreen VirtualViews on iOS by setting hidden = YES to avoid extra cost of views - */ -export const hideOffscreenVirtualViewsOnIOS: Getter = createNativeFlagGetter('hideOffscreenVirtualViewsOnIOS', false); /** * When enabled, uses optimized platform-specific paths to apply animated props synchronously. On Android, this uses a batched int/double buffer protocol with a single JNI call. On iOS, this passes AnimatedProps directly through the delegate chain and applies them via cloneProps, avoiding the folly::dynamic round-trip. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 40cae550b5ca..1c2a204dff1c 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -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<<7b1756a74caa546933eebb934d27de12>> + * @generated SignedSource<<4f1cda704a4ec31a005ded7ee8df3cbf>> * @flow strict * @noformat */ @@ -84,7 +84,6 @@ export interface Spec extends TurboModule { readonly fuseboxFrameRecordingEnabled?: () => boolean; readonly fuseboxNetworkInspectionEnabled?: () => boolean; readonly fuseboxScreenshotCaptureEnabled?: () => boolean; - readonly hideOffscreenVirtualViewsOnIOS?: () => boolean; readonly optimizedAnimatedPropUpdates?: () => boolean; readonly overrideBySynchronousMountPropsAtMountingAndroid?: () => boolean; readonly perfIssuesEnabled?: () => boolean; From a160cac8afe9f8b0f724c4ec8c2428e484d671c0 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Tue, 16 Jun 2026 07:59:02 -0700 Subject: [PATCH 007/561] Mark loaderRequest __unused in RCTSyncImageManager to fix release-build unused-variable error (#57227) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57227 Changelog: [Internal] Reviewed By: ellemac123 Differential Revision: D108445102 fbshipit-source-id: 5bc01229668d233ca8d8260801dca3b0bada6e2d --- .../ios/react/renderer/imagemanager/RCTSyncImageManager.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTSyncImageManager.mm b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTSyncImageManager.mm index f9fb45fef965..43fbb6a66043 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTSyncImageManager.mm +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTSyncImageManager.mm @@ -78,7 +78,7 @@ - (ImageRequest)requestImage:(ImageSource)imageSource observerCoordinator->nativeImageResponseProgress((float)progress / (float)total, progress, total); }; - RCTImageURLLoaderRequest *loaderRequest = + RCTImageURLLoaderRequest *__unused loaderRequest = [self->_imageLoader loadImageWithURLRequest:request size:CGSizeMake(imageSource.size.width, imageSource.size.height) scale:imageSource.scale From 723908a75992c116f4c4315d0665d32d0150f0b7 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Tue, 16 Jun 2026 09:00:32 -0700 Subject: [PATCH 008/561] Remove useOptimizedViewRegistryOnAndroid feature flag (#57228) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57228 The flag gated a more memory-efficient view registry implementation in `SurfaceMountingManager` (`MutableIntObjectMap` with a `ReadWriteLock` instead of `ConcurrentHashMap`). Removing the gate, keeping the optimized path, and inlining the helper methods that previously dispatched between the two implementations. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D108415790 fbshipit-source-id: b21cbb1923cf7d15e375df8d3c3c51d187eecee3 --- .../fabric/mounting/SurfaceMountingManager.kt | 154 ++++++------------ .../featureflags/ReactNativeFeatureFlags.kt | 8 +- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 +- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 +- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +- .../featureflags/ReactNativeFeatureFlags.h | 7 +- .../ReactNativeFeatureFlagsAccessor.cpp | 34 +--- .../ReactNativeFeatureFlagsAccessor.h | 6 +- .../ReactNativeFeatureFlagsDefaults.h | 6 +- .../ReactNativeFeatureFlagsDynamicProvider.h | 11 +- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +- .../NativeReactNativeFeatureFlags.h | 4 +- .../ReactNativeFeatureFlags.config.js | 11 -- .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 21 files changed, 75 insertions(+), 250 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt index 984aa3e12067..b43cdbd20ede 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt @@ -55,7 +55,6 @@ import com.facebook.systrace.Systrace import java.util.ArrayDeque import java.util.LinkedList import java.util.Queue -import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.locks.ReentrantReadWriteLock import kotlin.concurrent.Volatile import kotlin.concurrent.read @@ -87,20 +86,9 @@ internal constructor( public var context: ThemedReactContext? = reactContext private set - private val tagToViewState: ConcurrentHashMap? - private val optimizedTagToViewState: MutableIntObjectMap? + private val tagToViewState: MutableIntObjectMap = MutableIntObjectMap() private val registryLock = ReentrantReadWriteLock() - init { - if (ReactNativeFeatureFlags.useOptimizedViewRegistryOnAndroid()) { - tagToViewState = null - optimizedTagToViewState = MutableIntObjectMap() - } else { - tagToViewState = ConcurrentHashMap() - optimizedTagToViewState = null - } - } - private val onViewAttachMountItems: Queue = ArrayDeque() // These are all non-null, until StopSurface is called @@ -142,7 +130,9 @@ internal constructor( return } - registryPut(surfaceId, ViewState(surfaceId, rootView, rootViewManager, true)) + registryLock.write { + tagToViewState[surfaceId] = ViewState(surfaceId, rootView, rootViewManager, true) + } val runnable: Runnable = object : GuardedRunnable(checkNotNull(context)) { @@ -206,7 +196,7 @@ internal constructor( if (tagSetForStoppedSurface?.containsKey(tag) == true) { return true } - return registryContains(tag) + return registryLock.read { tagToViewState.containsKey(tag) } } @UiThread @@ -252,12 +242,14 @@ internal constructor( // Reset all StateWrapper objects // Since this can happen on any thread, is it possible to race between StateWrapper destruction // and some accesses from View classes in the UI thread? - registryForEachValue { viewState -> - viewState.stateWrapper?.destroyState() - viewState.stateWrapper = null + registryLock.read { + tagToViewState.forEachValue { viewState -> + viewState.stateWrapper?.destroyState() + viewState.stateWrapper = null - viewState.eventEmitter?.destroy() - viewState.eventEmitter = null + viewState.eventEmitter?.destroy() + viewState.eventEmitter = null + } } val runnable = Runnable { @@ -265,29 +257,23 @@ internal constructor( viewManagerRegistry?.onSurfaceStopped(surfaceId) } - if (optimizedTagToViewState != null) { - val viewStatesToDelete: ArrayList - registryLock.write { - val tagSetForStoppedSurface = - SparseArrayCompat().also { this.tagSetForStoppedSurface = it } - viewStatesToDelete = ArrayList(optimizedTagToViewState.size) - optimizedTagToViewState.forEach { key, value -> - tagSetForStoppedSurface[key] = this@SurfaceMountingManager - viewStatesToDelete.add(value) - } - optimizedTagToViewState.clear() - } - for (viewState in viewStatesToDelete) { - onViewStateDeleted(viewState) + // Using this as a placeholder value in the map. We're using SparseArrayCompat + // since it can efficiently represent the list of pending tags + val tagSetForStoppedSurface = + SparseArrayCompat().also { this.tagSetForStoppedSurface = it } + + val viewStatesToDelete: ArrayList + registryLock.write { + viewStatesToDelete = ArrayList(tagToViewState.size) + tagToViewState.forEach { key, value -> + tagSetForStoppedSurface[key] = this@SurfaceMountingManager + viewStatesToDelete.add(value) } - } else { - val tagSetForStoppedSurface = - SparseArrayCompat().also { this.tagSetForStoppedSurface = it } - for ((key, value) in tagToViewState!!) { - tagSetForStoppedSurface[key] = this - onViewStateDeleted(value) - } - tagToViewState!!.clear() + tagToViewState.clear() + } + for (viewState in viewStatesToDelete) { + // We must call `onDropViewInstance` on all remaining Views + onViewStateDeleted(viewState) } // Evict all views from cache and memory @@ -602,7 +588,7 @@ internal constructor( this.stateWrapper = stateWrapper this.eventEmitter = eventEmitterWrapper } - registryPut(reactTag, viewState) + registryLock.write { tagToViewState[reactTag] = viewState } if (isLayoutable) { @Suppress("UNCHECKED_CAST") @@ -977,17 +963,9 @@ internal constructor( // TODO T62717437 - Use a flag to determine that these event emitters belong to virtual nodes // only. - val viewState: ViewState = - if (optimizedTagToViewState != null) { - registryLock.write { optimizedTagToViewState.getOrPut(reactTag) { ViewState(reactTag) } } - } else { - var vs = tagToViewState!![reactTag] - if (vs == null) { - vs = ViewState(reactTag) - tagToViewState!![reactTag] = vs - } - vs - } + val viewState: ViewState = registryLock.write { + tagToViewState.getOrPut(reactTag) { ViewState(reactTag) } + } val previousEventEmitterWrapper = viewState.eventEmitter synchronized(viewState) { @@ -1096,7 +1074,7 @@ internal constructor( // To delete we simply remove the tag from the registry. // We want to rely on the correct set of MountInstructions being sent to the platform, // or StopSurface being called, so we do not handle deleting descendants of the View. - registryRemove(reactTag) + registryLock.write { tagToViewState.remove(reactTag) } onViewStateDeleted(viewState) } @@ -1141,51 +1119,13 @@ internal constructor( } private fun getViewState(reactTag: Int): ViewState = - registryGet(reactTag) + getNullableViewState(reactTag) ?: throw RetryableMountingLayerException( "Unable to find viewState for tag $reactTag. Surface stopped: $isStopped" ) - private fun getNullableViewState(reactTag: Int): ViewState? = registryGet(reactTag) - - private fun registryGet(tag: Int): ViewState? { - return if (optimizedTagToViewState != null) { - registryLock.read { optimizedTagToViewState[tag] } - } else { - tagToViewState!![tag] - } - } - - private fun registryPut(tag: Int, state: ViewState) { - if (optimizedTagToViewState != null) { - registryLock.write { optimizedTagToViewState[tag] = state } - } else { - tagToViewState!![tag] = state - } - } - - private fun registryRemove(tag: Int) { - if (optimizedTagToViewState != null) { - registryLock.write { optimizedTagToViewState.remove(tag) } - } else { - tagToViewState!!.remove(tag) - } - } - - private fun registryContains(tag: Int): Boolean { - return if (optimizedTagToViewState != null) { - registryLock.read { optimizedTagToViewState.containsKey(tag) } - } else { - tagToViewState!!.containsKey(tag) - } - } - - private inline fun registryForEachValue(action: (ViewState) -> Unit) { - if (optimizedTagToViewState != null) { - registryLock.read { optimizedTagToViewState.forEachValue(action) } - } else { - tagToViewState!!.values.forEach(action) - } + private inline fun getNullableViewState(reactTag: Int): ViewState? = registryLock.read { + tagToViewState[reactTag] } /** Applies a bitmap as the background of the view with the given tag, if it exists. */ @@ -1197,16 +1137,18 @@ internal constructor( public fun printSurfaceState(): Unit { FLog.e(TAG, "Views created for surface $surfaceId:") - registryForEachValue { viewState -> - val viewManagerName = viewState.viewManager?.name - val view = viewState.view - val parent = if (view != null) view.parent as View? else null - val parentTag = parent?.id + registryLock.read { + tagToViewState.forEachValue { viewState -> + val viewManagerName = viewState.viewManager?.name + val view = viewState.view + val parent = if (view != null) view.parent as View? else null + val parentTag = parent?.id - FLog.e( - TAG, - "<$viewManagerName id=${viewState.reactTag} parentTag=$parentTag isRoot=${viewState.isRoot} />", - ) + FLog.e( + TAG, + "<$viewManagerName id=${viewState.reactTag} parentTag=$parentTag isRoot=${viewState.isRoot} />", + ) + } } } @@ -1219,7 +1161,7 @@ internal constructor( @EventCategoryDef eventCategory: Int, eventTimestamp: Long, ) { - val viewState = registryGet(reactTag) + val viewState = getNullableViewState(reactTag) if (viewState == null) { FLog.i(TAG, "Unable to invoke event: %s for reactTag: %d", eventName, reactTag) return diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index dc61e2a20f39..997717fe9055 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -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<<17567d3adfba54ec2f888b50dae9efb8>> + * @generated SignedSource<> */ /** @@ -498,12 +498,6 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun useNestedScrollViewAndroid(): Boolean = accessor.useNestedScrollViewAndroid() - /** - * Use MutableIntObjectMap with ReadWriteLock instead of ConcurrentHashMap for the view registry in SurfaceMountingManager to reduce memory overhead and GC pressure. - */ - @JvmStatic - public fun useOptimizedViewRegistryOnAndroid(): Boolean = accessor.useOptimizedViewRegistryOnAndroid() - /** * Use shared animation backend in C++ Animated */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index 7f003892085f..d6cfca387018 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -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<<337b652caa9d443c8d83915e22210198>> + * @generated SignedSource<<5bf52aa57fc011858db9f632930bb8fb>> */ /** @@ -98,7 +98,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var useFabricInteropCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useNestedScrollViewAndroidCache: Boolean? = null - private var useOptimizedViewRegistryOnAndroidCache: Boolean? = null private var useSharedAnimatedBackendCache: Boolean? = null private var useTraitHiddenOnAndroidCache: Boolean? = null private var useTurboModuleInteropCache: Boolean? = null @@ -809,15 +808,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun useOptimizedViewRegistryOnAndroid(): Boolean { - var cached = useOptimizedViewRegistryOnAndroidCache - if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.useOptimizedViewRegistryOnAndroid() - useOptimizedViewRegistryOnAndroidCache = cached - } - return cached - } - override fun useSharedAnimatedBackend(): Boolean { var cached = useSharedAnimatedBackendCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index 98bf3882ee23..f43d355cfb17 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -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<> + * @generated SignedSource<<4c03e1b03360e7703ffd1d7aa0afc277>> */ /** @@ -184,8 +184,6 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun useNestedScrollViewAndroid(): Boolean - @DoNotStrip @JvmStatic public external fun useOptimizedViewRegistryOnAndroid(): Boolean - @DoNotStrip @JvmStatic public external fun useSharedAnimatedBackend(): Boolean @DoNotStrip @JvmStatic public external fun useTraitHiddenOnAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index 4732a92c631b..54ff24362e67 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -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<> + * @generated SignedSource<<98ed9f6f027f919cd31cd1e890750684>> */ /** @@ -179,8 +179,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun useNestedScrollViewAndroid(): Boolean = false - override fun useOptimizedViewRegistryOnAndroid(): Boolean = false - override fun useSharedAnimatedBackend(): Boolean = false override fun useTraitHiddenOnAndroid(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 23633e4d7536..8dbf083ab9b7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -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<<164c9c2751f660ee098c12b8cf2c8b66>> + * @generated SignedSource<> */ /** @@ -102,7 +102,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var useFabricInteropCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useNestedScrollViewAndroidCache: Boolean? = null - private var useOptimizedViewRegistryOnAndroidCache: Boolean? = null private var useSharedAnimatedBackendCache: Boolean? = null private var useTraitHiddenOnAndroidCache: Boolean? = null private var useTurboModuleInteropCache: Boolean? = null @@ -891,16 +890,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } - override fun useOptimizedViewRegistryOnAndroid(): Boolean { - var cached = useOptimizedViewRegistryOnAndroidCache - if (cached == null) { - cached = currentProvider.useOptimizedViewRegistryOnAndroid() - accessedFeatureFlags.add("useOptimizedViewRegistryOnAndroid") - useOptimizedViewRegistryOnAndroidCache = cached - } - return cached - } - override fun useSharedAnimatedBackend(): Boolean { var cached = useSharedAnimatedBackendCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 50460e763de9..8855e869f5b5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -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<> + * @generated SignedSource<<4f18bde7c0680691cd6fceb63c41ad65>> */ /** @@ -179,8 +179,6 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun useNestedScrollViewAndroid(): Boolean - @DoNotStrip public fun useOptimizedViewRegistryOnAndroid(): Boolean - @DoNotStrip public fun useSharedAnimatedBackend(): Boolean @DoNotStrip public fun useTraitHiddenOnAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 04c199adaf00..bf7907626ecb 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -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<> + * @generated SignedSource<<13e7b6ef510a97b4210de914a015ae11>> */ /** @@ -507,12 +507,6 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } - bool useOptimizedViewRegistryOnAndroid() override { - static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useOptimizedViewRegistryOnAndroid"); - return method(javaProvider_); - } - bool useSharedAnimatedBackend() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useSharedAnimatedBackend"); @@ -949,11 +943,6 @@ bool JReactNativeFeatureFlagsCxxInterop::useNestedScrollViewAndroid( return ReactNativeFeatureFlags::useNestedScrollViewAndroid(); } -bool JReactNativeFeatureFlagsCxxInterop::useOptimizedViewRegistryOnAndroid( - facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::useOptimizedViewRegistryOnAndroid(); -} - bool JReactNativeFeatureFlagsCxxInterop::useSharedAnimatedBackend( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::useSharedAnimatedBackend(); @@ -1254,9 +1243,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "useNestedScrollViewAndroid", JReactNativeFeatureFlagsCxxInterop::useNestedScrollViewAndroid), - makeNativeMethod( - "useOptimizedViewRegistryOnAndroid", - JReactNativeFeatureFlagsCxxInterop::useOptimizedViewRegistryOnAndroid), makeNativeMethod( "useSharedAnimatedBackend", JReactNativeFeatureFlagsCxxInterop::useSharedAnimatedBackend), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index 591be913bf2d..a8a0831561ab 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -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<> + * @generated SignedSource<<4234522fd98acef7836d8050d0e7c82d>> */ /** @@ -264,9 +264,6 @@ class JReactNativeFeatureFlagsCxxInterop static bool useNestedScrollViewAndroid( facebook::jni::alias_ref); - static bool useOptimizedViewRegistryOnAndroid( - facebook::jni::alias_ref); - static bool useSharedAnimatedBackend( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 78aefa5b9713..a0227722197a 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -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<> + * @generated SignedSource<<0bafa89fa8781cb3c7aebf5d0bb8678e>> */ /** @@ -338,10 +338,6 @@ bool ReactNativeFeatureFlags::useNestedScrollViewAndroid() { return getAccessor().useNestedScrollViewAndroid(); } -bool ReactNativeFeatureFlags::useOptimizedViewRegistryOnAndroid() { - return getAccessor().useOptimizedViewRegistryOnAndroid(); -} - bool ReactNativeFeatureFlags::useSharedAnimatedBackend() { return getAccessor().useSharedAnimatedBackend(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 37e9094d1b41..f00873e7700b 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -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<> + * @generated SignedSource<<3fca574dc84a346c113e479d0583537c>> */ /** @@ -429,11 +429,6 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool useNestedScrollViewAndroid(); - /** - * Use MutableIntObjectMap with ReadWriteLock instead of ConcurrentHashMap for the view registry in SurfaceMountingManager to reduce memory overhead and GC pressure. - */ - RN_EXPORT static bool useOptimizedViewRegistryOnAndroid(); - /** * Use shared animation backend in C++ Animated */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 0a550efaf0e7..5d234f7446f7 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -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<<1c4a88ac3f4f2d04d2e9d986536df7d9>> + * @generated SignedSource<<1ee65c6b449518e6ae582aa61effa2e3>> */ /** @@ -1433,24 +1433,6 @@ bool ReactNativeFeatureFlagsAccessor::useNestedScrollViewAndroid() { return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::useOptimizedViewRegistryOnAndroid() { - auto flagValue = useOptimizedViewRegistryOnAndroid_.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(78, "useOptimizedViewRegistryOnAndroid"); - - flagValue = currentProvider_->useOptimizedViewRegistryOnAndroid(); - useOptimizedViewRegistryOnAndroid_ = flagValue; - } - - return flagValue.value(); -} - bool ReactNativeFeatureFlagsAccessor::useSharedAnimatedBackend() { auto flagValue = useSharedAnimatedBackend_.load(); @@ -1460,7 +1442,7 @@ bool ReactNativeFeatureFlagsAccessor::useSharedAnimatedBackend() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(79, "useSharedAnimatedBackend"); + markFlagAsAccessed(78, "useSharedAnimatedBackend"); flagValue = currentProvider_->useSharedAnimatedBackend(); useSharedAnimatedBackend_ = flagValue; @@ -1478,7 +1460,7 @@ bool ReactNativeFeatureFlagsAccessor::useTraitHiddenOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(80, "useTraitHiddenOnAndroid"); + markFlagAsAccessed(79, "useTraitHiddenOnAndroid"); flagValue = currentProvider_->useTraitHiddenOnAndroid(); useTraitHiddenOnAndroid_ = flagValue; @@ -1496,7 +1478,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(81, "useTurboModuleInterop"); + markFlagAsAccessed(80, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1514,7 +1496,7 @@ double ReactNativeFeatureFlagsAccessor::viewCullingOutsetRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(82, "viewCullingOutsetRatio"); + markFlagAsAccessed(81, "viewCullingOutsetRatio"); flagValue = currentProvider_->viewCullingOutsetRatio(); viewCullingOutsetRatio_ = flagValue; @@ -1532,7 +1514,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(83, "viewTransitionEnabled"); + markFlagAsAccessed(82, "viewTransitionEnabled"); flagValue = currentProvider_->viewTransitionEnabled(); viewTransitionEnabled_ = flagValue; @@ -1550,7 +1532,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionUseHardwareBitmapAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(84, "viewTransitionUseHardwareBitmapAndroid"); + markFlagAsAccessed(83, "viewTransitionUseHardwareBitmapAndroid"); flagValue = currentProvider_->viewTransitionUseHardwareBitmapAndroid(); viewTransitionUseHardwareBitmapAndroid_ = flagValue; @@ -1568,7 +1550,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(85, "virtualViewPrerenderRatio"); + markFlagAsAccessed(84, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 10aec19ebdc0..c5419463dd3c 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -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<<9961a0c8efe857161fb861f2873a3749>> + * @generated SignedSource<<80fcb1756caccd2259335a67984d76d5>> */ /** @@ -110,7 +110,6 @@ class ReactNativeFeatureFlagsAccessor { bool useFabricInterop(); bool useNativeViewConfigsInBridgelessMode(); bool useNestedScrollViewAndroid(); - bool useOptimizedViewRegistryOnAndroid(); bool useSharedAnimatedBackend(); bool useTraitHiddenOnAndroid(); bool useTurboModuleInterop(); @@ -129,7 +128,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 86> accessedFeatureFlags_; + std::array, 85> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -209,7 +208,6 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> useFabricInterop_; std::atomic> useNativeViewConfigsInBridgelessMode_; std::atomic> useNestedScrollViewAndroid_; - std::atomic> useOptimizedViewRegistryOnAndroid_; std::atomic> useSharedAnimatedBackend_; std::atomic> useTraitHiddenOnAndroid_; std::atomic> useTurboModuleInterop_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index d85cb77a016a..42e2ddea7424 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -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<> + * @generated SignedSource<<94d2315cb9bfc2684e18770eff3a1cf6>> */ /** @@ -339,10 +339,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } - bool useOptimizedViewRegistryOnAndroid() override { - return false; - } - bool useSharedAnimatedBackend() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 3558ac5a30a1..a2e10dda1703 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -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<<6db86679458aa76ebb30082ba12a32ae>> + * @generated SignedSource<<215e8b28994854f31f249a5e51623c87>> */ /** @@ -747,15 +747,6 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::useNestedScrollViewAndroid(); } - bool useOptimizedViewRegistryOnAndroid() override { - auto value = values_["useOptimizedViewRegistryOnAndroid"]; - if (!value.isNull()) { - return value.getBool(); - } - - return ReactNativeFeatureFlagsDefaults::useOptimizedViewRegistryOnAndroid(); - } - bool useSharedAnimatedBackend() override { auto value = values_["useSharedAnimatedBackend"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 956231ed0477..aac79cc9f568 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -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<> + * @generated SignedSource<> */ /** @@ -103,7 +103,6 @@ class ReactNativeFeatureFlagsProvider { virtual bool useFabricInterop() = 0; virtual bool useNativeViewConfigsInBridgelessMode() = 0; virtual bool useNestedScrollViewAndroid() = 0; - virtual bool useOptimizedViewRegistryOnAndroid() = 0; virtual bool useSharedAnimatedBackend() = 0; virtual bool useTraitHiddenOnAndroid() = 0; virtual bool useTurboModuleInterop() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 83802a955650..594d3c9d7b1b 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -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<> + * @generated SignedSource<> */ /** @@ -434,11 +434,6 @@ bool NativeReactNativeFeatureFlags::useNestedScrollViewAndroid( return ReactNativeFeatureFlags::useNestedScrollViewAndroid(); } -bool NativeReactNativeFeatureFlags::useOptimizedViewRegistryOnAndroid( - jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::useOptimizedViewRegistryOnAndroid(); -} - bool NativeReactNativeFeatureFlags::useSharedAnimatedBackend( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::useSharedAnimatedBackend(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index e29d9ac03b8e..b5ddcd8a969f 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -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<> + * @generated SignedSource<<92d22193e04fdbd6cfb119d69496c065>> */ /** @@ -192,8 +192,6 @@ class NativeReactNativeFeatureFlags bool useNestedScrollViewAndroid(jsi::Runtime& runtime); - bool useOptimizedViewRegistryOnAndroid(jsi::Runtime& runtime); - bool useSharedAnimatedBackend(jsi::Runtime& runtime); bool useTraitHiddenOnAndroid(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index be1206256523..9d7ca7f313be 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -882,17 +882,6 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, - useOptimizedViewRegistryOnAndroid: { - defaultValue: false, - metadata: { - dateAdded: '2026-04-28', - description: - 'Use MutableIntObjectMap with ReadWriteLock instead of ConcurrentHashMap for the view registry in SurfaceMountingManager to reduce memory overhead and GC pressure.', - expectedReleaseValue: true, - purpose: 'experimentation', - }, - ossReleaseStage: 'none', - }, useSharedAnimatedBackend: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index b3b3f6a2eca2..c68254956dc1 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -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<<785d84f617e6b1870c3ff1eeed9f1c66>> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -127,7 +127,6 @@ export type ReactNativeFeatureFlags = Readonly<{ useFabricInterop: Getter, useNativeViewConfigsInBridgelessMode: Getter, useNestedScrollViewAndroid: Getter, - useOptimizedViewRegistryOnAndroid: Getter, useSharedAnimatedBackend: Getter, useTraitHiddenOnAndroid: Getter, useTurboModuleInterop: Getter, @@ -523,10 +522,6 @@ export const useNativeViewConfigsInBridgelessMode: Getter = createNativ * When enabled, ReactScrollView will extend NestedScrollView instead of ScrollView on Android for improved nested scrolling support. */ export const useNestedScrollViewAndroid: Getter = createNativeFlagGetter('useNestedScrollViewAndroid', false); -/** - * Use MutableIntObjectMap with ReadWriteLock instead of ConcurrentHashMap for the view registry in SurfaceMountingManager to reduce memory overhead and GC pressure. - */ -export const useOptimizedViewRegistryOnAndroid: Getter = createNativeFlagGetter('useOptimizedViewRegistryOnAndroid', false); /** * Use shared animation backend in C++ Animated */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 1c2a204dff1c..263f1ad402d4 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -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<<4f1cda704a4ec31a005ded7ee8df3cbf>> + * @generated SignedSource<<6bbb0c4532c0762c4ae2dd1d7bc43fb9>> * @flow strict * @noformat */ @@ -103,7 +103,6 @@ export interface Spec extends TurboModule { readonly useFabricInterop?: () => boolean; readonly useNativeViewConfigsInBridgelessMode?: () => boolean; readonly useNestedScrollViewAndroid?: () => boolean; - readonly useOptimizedViewRegistryOnAndroid?: () => boolean; readonly useSharedAnimatedBackend?: () => boolean; readonly useTraitHiddenOnAndroid?: () => boolean; readonly useTurboModuleInterop?: () => boolean; From fc7dc741d2b9dcdc36660d100a1b4ba420f8b725 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Tue, 16 Jun 2026 11:18:24 -0700 Subject: [PATCH 009/561] Flip cxxNativeAnimatedEnabled featureflag default to true (#57204) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57204 ## Changelog: [General] [Changed] - Flip cxxNativeAnimatedEnabled featureflag default to true Reviewed By: javache Differential Revision: D108323433 fbshipit-source-id: 7f8157013bd7369ef520348db8b3f2eaf19a5e35 --- .../ReactNativeFeatureFlagsDefaults.kt | 4 +-- .../ReactNativeFeatureFlagsDefaults.h | 4 +-- .../ReactNativeFeatureFlags.config.js | 2 +- .../private/animated/NativeAnimatedHelper.js | 25 +++++++++++++------ .../featureflags/ReactNativeFeatureFlags.js | 4 +-- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index 54ff24362e67..9e708427b7df 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -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<<98ed9f6f027f919cd31cd1e890750684>> + * @generated SignedSource<<0dcc15b419f6805bdbeec4727ad94761>> */ /** @@ -27,7 +27,7 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun cdpInteractionMetricsEnabled(): Boolean = false - override fun cxxNativeAnimatedEnabled(): Boolean = false + override fun cxxNativeAnimatedEnabled(): Boolean = true override fun defaultTextToOverflowHidden(): Boolean = true diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 42e2ddea7424..89637fbde8dd 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -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<<94d2315cb9bfc2684e18770eff3a1cf6>> + * @generated SignedSource<<613be235a200f15ac2ec48d1f5d87053>> */ /** @@ -36,7 +36,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { } bool cxxNativeAnimatedEnabled() override { - return false; + return true; } bool defaultTextToOverflowHidden() override { diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 9d7ca7f313be..35b17677b46f 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -72,7 +72,7 @@ const definitions: FeatureFlagDefinitions = { ossReleaseStage: 'none', }, cxxNativeAnimatedEnabled: { - defaultValue: false, + defaultValue: true, metadata: { dateAdded: '2025-03-14', description: diff --git a/packages/react-native/src/private/animated/NativeAnimatedHelper.js b/packages/react-native/src/private/animated/NativeAnimatedHelper.js index f27650b3d327..9afd64374e5c 100644 --- a/packages/react-native/src/private/animated/NativeAnimatedHelper.js +++ b/packages/react-native/src/private/animated/NativeAnimatedHelper.js @@ -71,6 +71,21 @@ let globalEventEmitterAnimationFinishedListener: ?EventSubscription = null; const shouldSignalBatch: boolean = ReactNativeFeatureFlags.cxxNativeAnimatedEnabled(); +// Schedules `API.flushQueue` after the current batch, replacing any pending +// flush. On device `setImmediate` is a microtask; under jest's fake timers it's +// a fake-timer entry that only `runAllTimers` drains — not `await` or +// `advanceTimersByTime` — so the deferred flush wouldn't run before a test's +// assertions. Flush synchronously in tests instead. +function scheduleQueueFlush(): void { + clearImmediate(flushQueueImmediate); + if (process.env.NODE_ENV === 'test') { + // TODO: T275950736 - remove this path + API.flushQueue(); + } else { + flushQueueImmediate = setImmediate(API.flushQueue); + } +} + function createNativeOperations(): NonNullable { const methodNames = [ 'createAnimatedNode', // 1 @@ -116,8 +131,7 @@ function createNativeOperations(): NonNullable { // details, see `NativeAnimatedModule.queueAndExecuteBatchedOperations`. singleOpQueue.push(operationID, ...args); if (shouldSignalBatch) { - clearImmediate(flushQueueImmediate); - flushQueueImmediate = setImmediate(API.flushQueue); + scheduleQueueFlush(); } }; } @@ -137,8 +151,7 @@ function createNativeOperations(): NonNullable { } else if (shouldSignalBatch) { // $FlowExpectedError[incompatible-call] - Dynamism. queue.push(() => method(...args)); - clearImmediate(flushQueueImmediate); - flushQueueImmediate = setImmediate(API.flushQueue); + scheduleQueueFlush(); } else { // $FlowExpectedError[incompatible-call] - Dynamism. method(...args); @@ -190,9 +203,7 @@ const API = { invariant(NativeAnimatedModule, 'Native animated module is not available'); if (ReactNativeFeatureFlags.animatedShouldDebounceQueueFlush()) { - const prevImmediate = flushQueueImmediate; - clearImmediate(prevImmediate); - flushQueueImmediate = setImmediate(API.flushQueue); + scheduleQueueFlush(); } else { API.flushQueue(); } diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index c68254956dc1..b8b706594ca5 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -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<> + * @generated SignedSource<<1f64eab49a337feb5c9b1b41faf92730>> * @flow strict * @noformat */ @@ -221,7 +221,7 @@ export const cdpInteractionMetricsEnabled: Getter = createNativeFlagGet /** * Use a C++ implementation of Native Animated instead of the platform implementation. */ -export const cxxNativeAnimatedEnabled: Getter = createNativeFlagGetter('cxxNativeAnimatedEnabled', false); +export const cxxNativeAnimatedEnabled: Getter = createNativeFlagGetter('cxxNativeAnimatedEnabled', true); /** * When enabled, sets the default overflow style for Text components to hidden instead of visible. */ From cffe14ff57ce0e76601e9efde833700d6ba609af Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Tue, 16 Jun 2026 13:16:23 -0700 Subject: [PATCH 010/561] remove `useNativeDriver` under featureflag animatedForceNativeDriver (#57211) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57211 ## Changelog: [General] [Added] - remove `useNativeDriver` under featureflag animatedForceNativeDriver When `animatedForceNativeDriver` is enabled, it forces `useNativeDriver` to `true` for all Animated animations and events, overriding the config (explicit `false` set by user will be no-op). Has no effect unless the shared animated backend is enabled, which is required to support native driver for all props. Also using this flag to gate the js animation logic that could be cleaned up when this path is fully working. Reviewed By: javache Differential Revision: D108193641 fbshipit-source-id: fa2c7332742435309fc00831d9644ca2cf2f6ab9 --- .../Animated/AnimatedImplementation.js | 19 +++++- .../Animated/NativeAnimatedAllowlist.js | 36 +++++++++++ .../__tests__/AnimatedBackend-itest.js | 59 +++++++++++++++++++ .../Animated/animations/Animation.js | 1 + .../Animated/animations/DecayAnimation.js | 1 + .../Animated/animations/SpringAnimation.js | 1 + .../Animated/animations/TimingAnimation.js | 1 + .../ReactNativeFeatureFlags.config.js | 11 ++++ .../private/animated/NativeAnimatedHelper.js | 25 +++++++- .../featureflags/ReactNativeFeatureFlags.js | 8 ++- 10 files changed, 155 insertions(+), 7 deletions(-) diff --git a/packages/react-native/Libraries/Animated/AnimatedImplementation.js b/packages/react-native/Libraries/Animated/AnimatedImplementation.js index 46a08d2e8954..d14425499cab 100644 --- a/packages/react-native/Libraries/Animated/AnimatedImplementation.js +++ b/packages/react-native/Libraries/Animated/AnimatedImplementation.js @@ -20,6 +20,7 @@ import type {DecayAnimationConfig} from './animations/DecayAnimation'; import type {SpringAnimationConfig} from './animations/SpringAnimation'; import type {TimingAnimationConfig} from './animations/TimingAnimation'; +import NativeAnimatedHelper from '../../src/private/animated/NativeAnimatedHelper'; import {AnimatedEvent, attachNativeEventImpl} from './AnimatedEvent'; import DecayAnimation from './animations/DecayAnimation'; import SpringAnimation from './animations/SpringAnimation'; @@ -200,7 +201,11 @@ const springImpl = function ( }, _isUsingNativeDriver: function (): boolean { - return config.useNativeDriver || false; + return ( + NativeAnimatedHelper.isNativeDriverForced() || + config.useNativeDriver || + false + ); }, } ); @@ -254,7 +259,11 @@ const timingImpl = function ( }, _isUsingNativeDriver: function (): boolean { - return config.useNativeDriver || false; + return ( + NativeAnimatedHelper.isNativeDriverForced() || + config.useNativeDriver || + false + ); }, } ); @@ -296,7 +305,11 @@ const decayImpl = function ( }, _isUsingNativeDriver: function (): boolean { - return config.useNativeDriver || false; + return ( + NativeAnimatedHelper.isNativeDriverForced() || + config.useNativeDriver || + false + ); }, } ); diff --git a/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js b/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js index c5cecfc828c6..c91017f23fc0 100644 --- a/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js +++ b/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js @@ -78,6 +78,42 @@ const SUPPORTED_STYLES: {[string]: true} = { top: true, /* flex */ flex: true, + flexGrow: true, + flexShrink: true, + flexBasis: true, + aspectRatio: true, + /* margin */ + margin: true, + marginLeft: true, + marginRight: true, + marginTop: true, + marginBottom: true, + marginStart: true, + marginEnd: true, + marginHorizontal: true, + marginVertical: true, + /* padding */ + padding: true, + paddingLeft: true, + paddingRight: true, + paddingTop: true, + paddingBottom: true, + paddingStart: true, + paddingEnd: true, + paddingHorizontal: true, + paddingVertical: true, + /* border width */ + borderWidth: true, + borderLeftWidth: true, + borderRightWidth: true, + borderTopWidth: true, + borderBottomWidth: true, + borderStartWidth: true, + borderEndWidth: true, + /* gap */ + gap: true, + rowGap: true, + columnGap: true, } : {}), }; diff --git a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js index adeaf7e485cf..57b72ea67715 100644 --- a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js +++ b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js @@ -21,6 +21,65 @@ import {Animated, View, useAnimatedValue} from 'react-native'; import {allowStyleProp} from 'react-native/Libraries/Animated/NativeAnimatedAllowlist'; import ReactNativeElement from 'react-native/src/private/webapis/dom/nodes/ReactNativeElement'; +// marginLeft (and the other margin props) are only on the native animated +// allowlist when the shared backend is enabled. This test deliberately does NOT +// call allowStyleProp('marginLeft') — it verifies the prop is supported natively +// out of the box under useSharedAnimatedBackend. +test('animate marginLeft layout prop', () => { + const viewRef = createRef(); + + let _animatedMarginLeft; + let _marginLeftAnimation; + + function MyApp() { + const animatedMarginLeft = useAnimatedValue(0); + _animatedMarginLeft = animatedMarginLeft; + return ( + + ); + } + + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render(); + }); + + Fantom.runTask(() => { + _marginLeftAnimation = Animated.timing(_animatedMarginLeft, { + toValue: 100, + duration: 200, + useNativeDriver: true, + }).start(); + }); + + Fantom.unstable_produceFramesForDuration(100); + + expect(root.getRenderedOutput({props: ['marginLeft']}).toJSX()).toEqual( + , + ); + + Fantom.unstable_produceFramesForDuration(100); + + // TODO: this shouldn't be necessary since animation should be stopped after duration + Fantom.runTask(() => { + _marginLeftAnimation?.stop(); + }); + + expect(root.getRenderedOutput({props: ['marginLeft']}).toJSX()).toEqual( + , + ); +}); + test('animated opacity', () => { let _opacity; let _opacityAnimation; diff --git a/packages/react-native/Libraries/Animated/animations/Animation.js b/packages/react-native/Libraries/Animated/animations/Animation.js index 7322ec03c6b3..83e1a715379a 100644 --- a/packages/react-native/Libraries/Animated/animations/Animation.js +++ b/packages/react-native/Libraries/Animated/animations/Animation.js @@ -70,6 +70,7 @@ export default class Animation { previousAnimation: ?Animation, animatedValue: AnimatedValue, ): void { + // TODO: T274006331 - Remove js-only animation once shared backend is fully rolled out if (!this._useNativeDriver && animatedValue.__isNative === true) { throw new Error( 'Attempting to run JS driven animation on animated node ' + diff --git a/packages/react-native/Libraries/Animated/animations/DecayAnimation.js b/packages/react-native/Libraries/Animated/animations/DecayAnimation.js index 35eb106f5a2b..d6b834b032ee 100644 --- a/packages/react-native/Libraries/Animated/animations/DecayAnimation.js +++ b/packages/react-native/Libraries/Animated/animations/DecayAnimation.js @@ -85,6 +85,7 @@ export default class DecayAnimation extends Animation { this._startTime = Date.now(); const useNativeDriver = this.__startAnimationIfNative(animatedValue); + // TODO: T274006331 - Remove js-only animation once shared backend is fully rolled out if (!useNativeDriver) { this._animationFrame = requestAnimationFrame(() => this.onUpdate()); } diff --git a/packages/react-native/Libraries/Animated/animations/SpringAnimation.js b/packages/react-native/Libraries/Animated/animations/SpringAnimation.js index cb70e4454117..f04a527469b3 100644 --- a/packages/react-native/Libraries/Animated/animations/SpringAnimation.js +++ b/packages/react-native/Libraries/Animated/animations/SpringAnimation.js @@ -225,6 +225,7 @@ export default class SpringAnimation extends Animation { const start = () => { const useNativeDriver = this.__startAnimationIfNative(animatedValue); + // TODO: T274006331 - Remove js-only animation once shared backend is fully rolled out if (!useNativeDriver) { this.onUpdate(); } diff --git a/packages/react-native/Libraries/Animated/animations/TimingAnimation.js b/packages/react-native/Libraries/Animated/animations/TimingAnimation.js index c464334cc376..dffb737a9882 100644 --- a/packages/react-native/Libraries/Animated/animations/TimingAnimation.js +++ b/packages/react-native/Libraries/Animated/animations/TimingAnimation.js @@ -129,6 +129,7 @@ export default class TimingAnimation extends Animation { this._startTime = Date.now(); const useNativeDriver = this.__startAnimationIfNative(animatedValue); + // TODO: T274006331 - Remove js-only animation once shared backend is fully rolled out if (!useNativeDriver) { // Animations that sometimes have 0 duration and sometimes do not // still need to use the native driver when duration is 0 so as to diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 35b17677b46f..108297dddc4a 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -970,6 +970,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + animatedForceNativeDriver: { + defaultValue: false, + metadata: { + dateAdded: '2026-06-10', + description: + 'When enabled, forces `useNativeDriver` to `true` for all Animated animations and events, overriding the config (including an explicit `false`). Has no effect unless the shared animated backend is enabled, which is required to support native driver for all props.', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, animatedShouldDebounceQueueFlush: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/animated/NativeAnimatedHelper.js b/packages/react-native/src/private/animated/NativeAnimatedHelper.js index 9afd64374e5c..74a76280692a 100644 --- a/packages/react-native/src/private/animated/NativeAnimatedHelper.js +++ b/packages/react-native/src/private/animated/NativeAnimatedHelper.js @@ -417,17 +417,35 @@ function assertNativeAnimatedModule(): void { let _warnedMissingNativeAnimated = false; +// Whether the native driver should be forced on for every animation, overriding +// the config (including an explicit `useNativeDriver: false`). This is only safe +// when the shared animated backend is enabled — that backend is what makes every +// prop drivable natively. Forcing native without it would break animations of +// props the legacy native driver doesn't support. +function isNativeDriverForced(): boolean { + return ( + ReactNativeFeatureFlags.animatedForceNativeDriver() && + ReactNativeFeatureFlags.cxxNativeAnimatedEnabled() && + // eslint-disable-next-line + ReactNativeFeatureFlags.useSharedAnimatedBackend() + ); +} + function shouldUseNativeDriver( config: Readonly<{...AnimationConfig, ...}> | EventConfig, ): boolean { - if (config.useNativeDriver == null) { + const forceNativeDriver = isNativeDriverForced(); + + if (config.useNativeDriver == null && !forceNativeDriver) { console.warn( 'Animated: `useNativeDriver` was not specified. This is a required ' + 'option and must be explicitly set to `true` or `false`', ); } - if (config.useNativeDriver === true && !NativeAnimatedModule) { + const useNativeDriver = forceNativeDriver || config.useNativeDriver === true; + + if (useNativeDriver === true && !NativeAnimatedModule) { if (process.env.NODE_ENV !== 'test') { if (!_warnedMissingNativeAnimated) { console.warn( @@ -443,7 +461,7 @@ function shouldUseNativeDriver( return false; } - return config.useNativeDriver || false; + return useNativeDriver; } function transformDataType(value: number | string): number | string { @@ -469,6 +487,7 @@ export default { assertNativeAnimatedModule, generateNewAnimationId, generateNewNodeTag, + isNativeDriverForced, // $FlowExpectedError[unsafe-getters-setters] - unsafe getter lint suppression // $FlowExpectedError[missing-type-arg] - unsafe getter lint suppression get nativeEventEmitter(): NativeEventEmitter { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index b8b706594ca5..e5a0abc9c972 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -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<<1f64eab49a337feb5c9b1b41faf92730>> + * @generated SignedSource<<960e77b9abee222a2f1480870a33560a>> * @flow strict * @noformat */ @@ -30,6 +30,7 @@ import { export type ReactNativeFeatureFlagsJsOnly = Readonly<{ jsOnlyTestFlag: Getter, animatedDeferStartOfTimingAnimations: Getter, + animatedForceNativeDriver: Getter, animatedShouldDebounceQueueFlush: Getter, animatedShouldSyncValueBeforeStartCallback: Getter, animatedShouldUseSingleOp: Getter, @@ -146,6 +147,11 @@ export const jsOnlyTestFlag: Getter = createJavaScriptFlagGetter('jsOnl */ export const animatedDeferStartOfTimingAnimations: Getter = createJavaScriptFlagGetter('animatedDeferStartOfTimingAnimations', false); +/** + * When enabled, forces `useNativeDriver` to `true` for all Animated animations and events, overriding the config (including an explicit `false`). Has no effect unless the shared animated backend is enabled, which is required to support native driver for all props. + */ +export const animatedForceNativeDriver: Getter = createJavaScriptFlagGetter('animatedForceNativeDriver', false); + /** * Enables an experimental flush-queue debouncing in Animated.js. */ From 71fee907fb9f75ecba210a9041cde7393c98697b Mon Sep 17 00:00:00 2001 From: Sam Zhou Date: Tue, 16 Jun 2026 13:38:46 -0700 Subject: [PATCH 011/561] Turn on `experimental.instance_t_objkit_fix` across fbsource roots (#57234) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57234 Reviewed By: panagosg7 Differential Revision: D108750949 fbshipit-source-id: 1a72cf63dfa409309694c98404333bd24126f510 --- packages/community-cli-plugin/src/utils/version.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/community-cli-plugin/src/utils/version.js b/packages/community-cli-plugin/src/utils/version.js index 27f455a8aaee..120971b656a7 100644 --- a/packages/community-cli-plugin/src/utils/version.js +++ b/packages/community-cli-plugin/src/utils/version.js @@ -88,6 +88,7 @@ Diff: ${styleText(['dim', 'underline'], newVersion?.diffUrl ?? 'none')} } } +// $FlowFixMe[incompatible-type-guard] function isDiffPurgeEntry(data: Partial): data is DiffPurge { return ( // $FlowFixMe[incompatible-type-guard] From c211822d2afb68ff1c84540c2925c464c2c04d14 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Tue, 16 Jun 2026 16:54:42 -0700 Subject: [PATCH 012/561] Remove unnecessary inline annotation (#57238) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57238 This is failing on GitHub CI because of -werror. Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D108792926 fbshipit-source-id: 6011b52d1338a425d2049bf0a48df5141ef69754 --- .../facebook/react/fabric/mounting/SurfaceMountingManager.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt index b43cdbd20ede..3b5816a7e21c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt @@ -1124,7 +1124,7 @@ internal constructor( "Unable to find viewState for tag $reactTag. Surface stopped: $isStopped" ) - private inline fun getNullableViewState(reactTag: Int): ViewState? = registryLock.read { + private fun getNullableViewState(reactTag: Int): ViewState? = registryLock.read { tagToViewState[reactTag] } From 2abba7c30270c25a91c4f3d931dc1fd4fa3cea66 Mon Sep 17 00:00:00 2001 From: Vlad Stoica Date: Wed, 17 Jun 2026 02:34:45 -0700 Subject: [PATCH 013/561] Revert D108193641: remove `useNativeDriver` under featureflag animatedForceNativeDriver Differential Revision: D108193641 Original commit changeset: fa2c73327424 Original Phabricator Diff: D108193641 fbshipit-source-id: 3457a060ac48bfc65f018493e06dbfc76e9e3d85 --- .../Animated/AnimatedImplementation.js | 19 +----- .../Animated/NativeAnimatedAllowlist.js | 36 ----------- .../__tests__/AnimatedBackend-itest.js | 59 ------------------- .../Animated/animations/Animation.js | 1 - .../Animated/animations/DecayAnimation.js | 1 - .../Animated/animations/SpringAnimation.js | 1 - .../Animated/animations/TimingAnimation.js | 1 - .../ReactNativeFeatureFlags.config.js | 11 ---- .../private/animated/NativeAnimatedHelper.js | 25 +------- .../featureflags/ReactNativeFeatureFlags.js | 8 +-- 10 files changed, 7 insertions(+), 155 deletions(-) diff --git a/packages/react-native/Libraries/Animated/AnimatedImplementation.js b/packages/react-native/Libraries/Animated/AnimatedImplementation.js index d14425499cab..46a08d2e8954 100644 --- a/packages/react-native/Libraries/Animated/AnimatedImplementation.js +++ b/packages/react-native/Libraries/Animated/AnimatedImplementation.js @@ -20,7 +20,6 @@ import type {DecayAnimationConfig} from './animations/DecayAnimation'; import type {SpringAnimationConfig} from './animations/SpringAnimation'; import type {TimingAnimationConfig} from './animations/TimingAnimation'; -import NativeAnimatedHelper from '../../src/private/animated/NativeAnimatedHelper'; import {AnimatedEvent, attachNativeEventImpl} from './AnimatedEvent'; import DecayAnimation from './animations/DecayAnimation'; import SpringAnimation from './animations/SpringAnimation'; @@ -201,11 +200,7 @@ const springImpl = function ( }, _isUsingNativeDriver: function (): boolean { - return ( - NativeAnimatedHelper.isNativeDriverForced() || - config.useNativeDriver || - false - ); + return config.useNativeDriver || false; }, } ); @@ -259,11 +254,7 @@ const timingImpl = function ( }, _isUsingNativeDriver: function (): boolean { - return ( - NativeAnimatedHelper.isNativeDriverForced() || - config.useNativeDriver || - false - ); + return config.useNativeDriver || false; }, } ); @@ -305,11 +296,7 @@ const decayImpl = function ( }, _isUsingNativeDriver: function (): boolean { - return ( - NativeAnimatedHelper.isNativeDriverForced() || - config.useNativeDriver || - false - ); + return config.useNativeDriver || false; }, } ); diff --git a/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js b/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js index c91017f23fc0..c5cecfc828c6 100644 --- a/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js +++ b/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js @@ -78,42 +78,6 @@ const SUPPORTED_STYLES: {[string]: true} = { top: true, /* flex */ flex: true, - flexGrow: true, - flexShrink: true, - flexBasis: true, - aspectRatio: true, - /* margin */ - margin: true, - marginLeft: true, - marginRight: true, - marginTop: true, - marginBottom: true, - marginStart: true, - marginEnd: true, - marginHorizontal: true, - marginVertical: true, - /* padding */ - padding: true, - paddingLeft: true, - paddingRight: true, - paddingTop: true, - paddingBottom: true, - paddingStart: true, - paddingEnd: true, - paddingHorizontal: true, - paddingVertical: true, - /* border width */ - borderWidth: true, - borderLeftWidth: true, - borderRightWidth: true, - borderTopWidth: true, - borderBottomWidth: true, - borderStartWidth: true, - borderEndWidth: true, - /* gap */ - gap: true, - rowGap: true, - columnGap: true, } : {}), }; diff --git a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js index 57b72ea67715..adeaf7e485cf 100644 --- a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js +++ b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js @@ -21,65 +21,6 @@ import {Animated, View, useAnimatedValue} from 'react-native'; import {allowStyleProp} from 'react-native/Libraries/Animated/NativeAnimatedAllowlist'; import ReactNativeElement from 'react-native/src/private/webapis/dom/nodes/ReactNativeElement'; -// marginLeft (and the other margin props) are only on the native animated -// allowlist when the shared backend is enabled. This test deliberately does NOT -// call allowStyleProp('marginLeft') — it verifies the prop is supported natively -// out of the box under useSharedAnimatedBackend. -test('animate marginLeft layout prop', () => { - const viewRef = createRef(); - - let _animatedMarginLeft; - let _marginLeftAnimation; - - function MyApp() { - const animatedMarginLeft = useAnimatedValue(0); - _animatedMarginLeft = animatedMarginLeft; - return ( - - ); - } - - const root = Fantom.createRoot(); - - Fantom.runTask(() => { - root.render(); - }); - - Fantom.runTask(() => { - _marginLeftAnimation = Animated.timing(_animatedMarginLeft, { - toValue: 100, - duration: 200, - useNativeDriver: true, - }).start(); - }); - - Fantom.unstable_produceFramesForDuration(100); - - expect(root.getRenderedOutput({props: ['marginLeft']}).toJSX()).toEqual( - , - ); - - Fantom.unstable_produceFramesForDuration(100); - - // TODO: this shouldn't be necessary since animation should be stopped after duration - Fantom.runTask(() => { - _marginLeftAnimation?.stop(); - }); - - expect(root.getRenderedOutput({props: ['marginLeft']}).toJSX()).toEqual( - , - ); -}); - test('animated opacity', () => { let _opacity; let _opacityAnimation; diff --git a/packages/react-native/Libraries/Animated/animations/Animation.js b/packages/react-native/Libraries/Animated/animations/Animation.js index 83e1a715379a..7322ec03c6b3 100644 --- a/packages/react-native/Libraries/Animated/animations/Animation.js +++ b/packages/react-native/Libraries/Animated/animations/Animation.js @@ -70,7 +70,6 @@ export default class Animation { previousAnimation: ?Animation, animatedValue: AnimatedValue, ): void { - // TODO: T274006331 - Remove js-only animation once shared backend is fully rolled out if (!this._useNativeDriver && animatedValue.__isNative === true) { throw new Error( 'Attempting to run JS driven animation on animated node ' + diff --git a/packages/react-native/Libraries/Animated/animations/DecayAnimation.js b/packages/react-native/Libraries/Animated/animations/DecayAnimation.js index d6b834b032ee..35eb106f5a2b 100644 --- a/packages/react-native/Libraries/Animated/animations/DecayAnimation.js +++ b/packages/react-native/Libraries/Animated/animations/DecayAnimation.js @@ -85,7 +85,6 @@ export default class DecayAnimation extends Animation { this._startTime = Date.now(); const useNativeDriver = this.__startAnimationIfNative(animatedValue); - // TODO: T274006331 - Remove js-only animation once shared backend is fully rolled out if (!useNativeDriver) { this._animationFrame = requestAnimationFrame(() => this.onUpdate()); } diff --git a/packages/react-native/Libraries/Animated/animations/SpringAnimation.js b/packages/react-native/Libraries/Animated/animations/SpringAnimation.js index f04a527469b3..cb70e4454117 100644 --- a/packages/react-native/Libraries/Animated/animations/SpringAnimation.js +++ b/packages/react-native/Libraries/Animated/animations/SpringAnimation.js @@ -225,7 +225,6 @@ export default class SpringAnimation extends Animation { const start = () => { const useNativeDriver = this.__startAnimationIfNative(animatedValue); - // TODO: T274006331 - Remove js-only animation once shared backend is fully rolled out if (!useNativeDriver) { this.onUpdate(); } diff --git a/packages/react-native/Libraries/Animated/animations/TimingAnimation.js b/packages/react-native/Libraries/Animated/animations/TimingAnimation.js index dffb737a9882..c464334cc376 100644 --- a/packages/react-native/Libraries/Animated/animations/TimingAnimation.js +++ b/packages/react-native/Libraries/Animated/animations/TimingAnimation.js @@ -129,7 +129,6 @@ export default class TimingAnimation extends Animation { this._startTime = Date.now(); const useNativeDriver = this.__startAnimationIfNative(animatedValue); - // TODO: T274006331 - Remove js-only animation once shared backend is fully rolled out if (!useNativeDriver) { // Animations that sometimes have 0 duration and sometimes do not // still need to use the native driver when duration is 0 so as to diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 108297dddc4a..35b17677b46f 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -970,17 +970,6 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, - animatedForceNativeDriver: { - defaultValue: false, - metadata: { - dateAdded: '2026-06-10', - description: - 'When enabled, forces `useNativeDriver` to `true` for all Animated animations and events, overriding the config (including an explicit `false`). Has no effect unless the shared animated backend is enabled, which is required to support native driver for all props.', - expectedReleaseValue: true, - purpose: 'experimentation', - }, - ossReleaseStage: 'none', - }, animatedShouldDebounceQueueFlush: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/animated/NativeAnimatedHelper.js b/packages/react-native/src/private/animated/NativeAnimatedHelper.js index 74a76280692a..9afd64374e5c 100644 --- a/packages/react-native/src/private/animated/NativeAnimatedHelper.js +++ b/packages/react-native/src/private/animated/NativeAnimatedHelper.js @@ -417,35 +417,17 @@ function assertNativeAnimatedModule(): void { let _warnedMissingNativeAnimated = false; -// Whether the native driver should be forced on for every animation, overriding -// the config (including an explicit `useNativeDriver: false`). This is only safe -// when the shared animated backend is enabled — that backend is what makes every -// prop drivable natively. Forcing native without it would break animations of -// props the legacy native driver doesn't support. -function isNativeDriverForced(): boolean { - return ( - ReactNativeFeatureFlags.animatedForceNativeDriver() && - ReactNativeFeatureFlags.cxxNativeAnimatedEnabled() && - // eslint-disable-next-line - ReactNativeFeatureFlags.useSharedAnimatedBackend() - ); -} - function shouldUseNativeDriver( config: Readonly<{...AnimationConfig, ...}> | EventConfig, ): boolean { - const forceNativeDriver = isNativeDriverForced(); - - if (config.useNativeDriver == null && !forceNativeDriver) { + if (config.useNativeDriver == null) { console.warn( 'Animated: `useNativeDriver` was not specified. This is a required ' + 'option and must be explicitly set to `true` or `false`', ); } - const useNativeDriver = forceNativeDriver || config.useNativeDriver === true; - - if (useNativeDriver === true && !NativeAnimatedModule) { + if (config.useNativeDriver === true && !NativeAnimatedModule) { if (process.env.NODE_ENV !== 'test') { if (!_warnedMissingNativeAnimated) { console.warn( @@ -461,7 +443,7 @@ function shouldUseNativeDriver( return false; } - return useNativeDriver; + return config.useNativeDriver || false; } function transformDataType(value: number | string): number | string { @@ -487,7 +469,6 @@ export default { assertNativeAnimatedModule, generateNewAnimationId, generateNewNodeTag, - isNativeDriverForced, // $FlowExpectedError[unsafe-getters-setters] - unsafe getter lint suppression // $FlowExpectedError[missing-type-arg] - unsafe getter lint suppression get nativeEventEmitter(): NativeEventEmitter { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index e5a0abc9c972..b8b706594ca5 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -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<<960e77b9abee222a2f1480870a33560a>> + * @generated SignedSource<<1f64eab49a337feb5c9b1b41faf92730>> * @flow strict * @noformat */ @@ -30,7 +30,6 @@ import { export type ReactNativeFeatureFlagsJsOnly = Readonly<{ jsOnlyTestFlag: Getter, animatedDeferStartOfTimingAnimations: Getter, - animatedForceNativeDriver: Getter, animatedShouldDebounceQueueFlush: Getter, animatedShouldSyncValueBeforeStartCallback: Getter, animatedShouldUseSingleOp: Getter, @@ -147,11 +146,6 @@ export const jsOnlyTestFlag: Getter = createJavaScriptFlagGetter('jsOnl */ export const animatedDeferStartOfTimingAnimations: Getter = createJavaScriptFlagGetter('animatedDeferStartOfTimingAnimations', false); -/** - * When enabled, forces `useNativeDriver` to `true` for all Animated animations and events, overriding the config (including an explicit `false`). Has no effect unless the shared animated backend is enabled, which is required to support native driver for all props. - */ -export const animatedForceNativeDriver: Getter = createJavaScriptFlagGetter('animatedForceNativeDriver', false); - /** * Enables an experimental flush-queue debouncing in Animated.js. */ From 6fa330693fba313a2fe1121545c1efd558b60983 Mon Sep 17 00:00:00 2001 From: 5ZYSZ3K Date: Wed, 17 Jun 2026 05:07:38 -0700 Subject: [PATCH 014/561] fix: yoga crash with display:none (#57197) Summary: X-link: https://github.com/react/yoga/pull/1976 It fixes this issue: https://github.com/react/react-native/issues/52349 Basically, in some rare cases, having an element with `display:none` style caused the app to crash. It was caused by a stale `hasNewLayout` flag on the hidden view That flag was always set in `computeFlexBasisForChildren` for elements with `display:none` style, but could be never consumed/reset, because of a cache hit or something. Since such elements contribute nothing to the layout sizes, I made the change to actually touch them only during actual layout passes ## Changelog: [GENERAL] [FIXED] - Crash: YogaLayoutableShadowNode.cpp: function layout: assertion failed (YGNodeGetOwner(childYogaNode) == &yogaNode_) https://github.com/react/react-native/issues/52349 Pull Request resolved: https://github.com/react/react-native/pull/57197 Test Plan: I created a reproduction repo: https://github.com/5ZYSZ3K/native-tabs-crash-repro, to see the issue And to see, that my change fixes it, you can switch to `patch-yoga` branch there, and install it again (don't forget to install pods with `RCT_USE_PREBUILT_RNCORE=0 RCT_USE_RN_DEP=0` variables) Reviewed By: christophpurrer Differential Revision: D108796888 Pulled By: javache fbshipit-source-id: 455e3ddbec760dbee875c02f0ed6266b9a417e9a --- .../View-yogaNodeOwnerAssertion-itest.js | 120 ++++++++++++++++++ .../yoga/yoga/algorithm/CalculateLayout.cpp | 15 ++- 2 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 packages/react-native/Libraries/Components/View/__tests__/View-yogaNodeOwnerAssertion-itest.js diff --git a/packages/react-native/Libraries/Components/View/__tests__/View-yogaNodeOwnerAssertion-itest.js b/packages/react-native/Libraries/Components/View/__tests__/View-yogaNodeOwnerAssertion-itest.js new file mode 100644 index 000000000000..49f36c1f2edb --- /dev/null +++ b/packages/react-native/Libraries/Components/View/__tests__/View-yogaNodeOwnerAssertion-itest.js @@ -0,0 +1,120 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; + +import * as Fantom from '@react-native/fantom'; +import * as React from 'react'; +import {useState} from 'react'; +import {TextInput, View} from 'react-native'; + +const VIEWPORT_WIDTH = 390; +const VIEWPORT_HEIGHT = 844; + +// State setters captured during render so the test can drive the two-step repro +// from outside the component. In RNTesterPlayground these are wired to two +// buttons ("Step 1: resize container" / "Step 2: restyle input"); here we call +// them directly, each inside its own `runTask` so every step is a full commit +// plus Yoga layout pass. +let triggerResize: () => void = () => {}; +let triggerRestyle: () => void = () => {}; + +function Repro(): React.MixedElement { + const [tall, setTall] = useState(false); + const [highlighted, setHighlighted] = useState(false); + + triggerResize = () => setTall(v => !v); + triggerRestyle = () => setHighlighted(v => !v); + + return ( + + {/* Step 1 changes the height of this wrapper. The row's own size is + content-determined and does not change. */} + + + {/* The centered wrapper + its `display: none` child are the nodes + whose Yoga ownership leaks across generations. */} + + + + + + + + ); +} + +// Repro for (New Architecture, debug build): +// +// Assertion failed: (YGNodeGetOwner(childYogaNode) == &yogaNode_), +// function layout, file YogaLayoutableShadowNode.cpp, line 709 +// +// Mechanism: +// +// 1. Step 1 resizes the container wrapping the row. The row's content-determined +// size does not change, so Yoga re-MEASURES the row subtree with new +// constraints (a measure-only pass: `zeroOutLayoutRecursively` wipes the +// `display: none` child and sets `hasNewLayout` on it) but restores the row's +// final layout from cache. RN's metrics traversal never visits the centered +// wrapper, so the `hasNewLayout` flag on the hidden child is never consumed -- +// it leaks across the commit. +// +// 2. Step 2 changes only the TextInput's props. Fabric clones the row with a new +// children list; `adoptYogaChild` clones the untouched centered wrapper via +// `clone({})`, which SHARES the hidden child's yoga node (stale +// `hasNewLayout`, owner = previous generation's wrapper). During layout the +// wrapper is a clean cache hit, so `cloneChildrenIfNeeded()` never repairs +// ownership -- yet `calculateLayoutInternal` still flags the wrapper with +// `hasNewLayout`. RN's traversal then descends into the wrapper, finds the +// shared hidden child flagged but owned by the old generation, and trips the +// assert. +// +// The KeyboardAvoidingView + focus/typing path reproduces the same sequence +// organically (keyboard resize = step 1, restyle-on-change = step 2). If Yoga +// aborts, `runTask` re-throws the native error synchronously and this test fails. +test('does not trip the Yoga node owner assertion after resize then restyle', () => { + const root = Fantom.createRoot({ + viewportWidth: VIEWPORT_WIDTH, + viewportHeight: VIEWPORT_HEIGHT, + }); + + // Initial commit + layout. + Fantom.runTask(() => { + root.render(); + }); + + // Step 1: resize container -> measure-only pass leaks `hasNewLayout` on the + // hidden child. + Fantom.runTask(() => { + triggerResize(); + }); + + // Step 2: restyle input -> clones the row, shares the hidden child's yoga node + // with stale ownership, and (when the bug is present) trips the assert during + // the layout pass. + Fantom.runTask(() => { + triggerRestyle(); + }); + + // Reaching this point means Yoga did not abort during the second layout pass. + expect(root.getRenderedOutput().toJSX()).not.toBe(null); + + root.destroy(); +}); diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index 1db7a5c21af9..6e7814be2a29 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -615,9 +615,18 @@ static float computeFlexBasisForChildren( for (auto child : children) { child->processDimensions(); if (child->style().display() == Display::None) { - zeroOutLayoutRecursively(child); - child->setHasNewLayout(true); - child->setDirty(false); + // Only mutate display: none children during layout passes. Zeroing them + // out during measure-only passes contributes nothing to the measurement, + // but sets `hasNewLayout` on nodes the parent's layout pass may never + // visit (e.g. when its layout is restored from cache, skipping + // `cloneChildrenIfNeeded()`). Such a leaked flag survives the commit and + // is copied into lazily-shared clones, later tripping the ownership + // assertion in `YogaLayoutableShadowNode::layout`. + if (performLayout) { + zeroOutLayoutRecursively(child); + child->setHasNewLayout(true); + child->setDirty(false); + } continue; } if (performLayout) { From 0cdb59f1b45b6c15ed9e96cc59927a143bcf5d4c Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Wed, 17 Jun 2026 05:19:06 -0700 Subject: [PATCH 015/561] Explicitly wake the main loop when scheduling a React revision merge (#57245) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57245 Changelog: [IOS][FIXED] Add an explicit wake up call to the main loop hen scheduling a React revision merge I could be possible that on idle screens the run loop is asleep, so without an explicit wake up call, the scheduled merges aren't processed. This diff adds an explicit wake call when a merge is scheduled. Reviewed By: rubennorte Differential Revision: D108610347 fbshipit-source-id: 5ea02237b2152072b49a29482617fabbee34259f --- .../react-native/React/Fabric/RCTSurfacePresenter.mm | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm index ab8f3c490780..0e4bbe376463 100644 --- a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm +++ b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm @@ -349,8 +349,16 @@ - (void)schedulerShouldMergeReactRevision:(SurfaceId)surfaceId return; } - std::lock_guard lock(_pendingReactRevisionMergesMutex); - _pendingReactRevisionMerges.insert(surfaceId); + bool needsWake = false; + { + std::lock_guard lock(_pendingReactRevisionMergesMutex); + needsWake = _pendingReactRevisionMerges.empty(); + _pendingReactRevisionMerges.insert(surfaceId); + } + + if (needsWake) { + CFRunLoopWakeUp(CFRunLoopGetMain()); + } } - (void)_mergeReactRevisionForSurfaceId:(SurfaceId)surfaceId From 79adce3942c9d7c1901e44f0c0a7a68b3e6c89e9 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Wed, 17 Jun 2026 05:26:37 -0700 Subject: [PATCH 016/561] Remove offscreen image request downgrading feature flag (#57226) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Pull Request resolved: https://github.com/react/react-native/pull/57226 This removes the experimental `enableImageRequestDowngradingForNonVisibleImages` feature flag and backs out the behavior it gated. When enabled, `ImageShadowNode` downgraded image requests to prefetch priority for images that layout determined did not intersect the viewport — threading an `ImageRequestPriority` through `ImageRequestParams` and the Apple image managers, and propagating per-node viewport frames during Yoga layout via `experimental_layoutOrigin`/`experimental_layoutFrame` on `LayoutContext`. The flag defaulted to off and was never enabled in a release, and the gated behavior did not deliver the expected improvement, so the feature is removed entirely: `` once again always requests at immediate priority. This deletes the feature flag, the `ImageRequestPriority` enum and the `ImageRequestParams::priority` field, the priority parameter on `RCTImageManager`/`RCTSyncImageManager`/`RCTImageManagerProtocol`, the `experimental_layout*` `LayoutContext` fields and their Yoga propagation, the iOS request-priority debug overlay, and the associated Fantom test scaffolding. The generated feature-flag sources and the C++ API snapshots are regenerated accordingly. Changelog: [Internal] Reviewed By: javache Differential Revision: D108411690 fbshipit-source-id: 1538ec699ed2857f3d3154d666fac43a1dc64cd1 --- .../__tests__/Image-requestPriority-itest.js | 455 ------------------ .../Image/RCTImageComponentView.mm | 76 --- .../featureflags/ReactNativeFeatureFlags.kt | 8 +- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 +- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 +- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +- .../featureflags/ReactNativeFeatureFlags.h | 7 +- .../ReactNativeFeatureFlagsAccessor.cpp | 134 +++--- .../ReactNativeFeatureFlagsAccessor.h | 6 +- .../ReactNativeFeatureFlagsDefaults.h | 6 +- .../ReactNativeFeatureFlagsDynamicProvider.h | 11 +- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +- .../NativeReactNativeFeatureFlags.h | 4 +- .../components/image/ImageShadowNode.cpp | 55 +-- .../components/image/ImageShadowNode.h | 2 +- .../view/YogaLayoutableShadowNode.cpp | 23 +- .../react/renderer/core/LayoutContext.h | 13 - .../imagemanager/ImageRequestParams.h | 2 - .../imagemanager/ImageRequestParams.h | 8 +- .../renderer/imagemanager/ImageManager.mm | 4 +- .../imagemanager/ImageRequestParams.h | 7 +- .../renderer/imagemanager/RCTImageManager.h | 3 +- .../renderer/imagemanager/RCTImageManager.mm | 6 +- .../imagemanager/RCTImageManagerProtocol.h | 3 +- .../RCTImagePrimitivesConversions.h | 13 - .../imagemanager/RCTSyncImageManager.h | 3 +- .../imagemanager/RCTSyncImageManager.mm | 6 +- .../react/renderer/imagemanager/primitives.h | 5 - .../ReactNativeFeatureFlags.config.js | 11 - .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- .../testing/fantom/specs/NativeFantom.js | 3 - .../tester/src/FantomImageManager.h | 78 --- .../tester/src/NativeFantom.cpp | 18 - .../tester/src/NativeFantom.h | 3 - .../tester/src/TesterAppDelegate.cpp | 4 - .../tester/src/TesterMountingManager.cpp | 1 - .../tester/src/TesterMountingManager.h | 2 - .../api-snapshots/ReactAndroidDebugCxx.api | 6 - .../api-snapshots/ReactAndroidNewarchCxx.api | 6 - .../api-snapshots/ReactAndroidReleaseCxx.api | 6 - .../api-snapshots/ReactAppleDebugCxx.api | 14 +- .../api-snapshots/ReactAppleNewarchCxx.api | 14 +- .../api-snapshots/ReactAppleReleaseCxx.api | 14 +- .../api-snapshots/ReactCommonDebugCxx.api | 5 - .../api-snapshots/ReactCommonNewarchCxx.api | 5 - .../api-snapshots/ReactCommonReleaseCxx.api | 5 - 53 files changed, 105 insertions(+), 1034 deletions(-) delete mode 100644 packages/react-native/Libraries/Image/__tests__/Image-requestPriority-itest.js delete mode 100644 private/react-native-fantom/tester/src/FantomImageManager.h diff --git a/packages/react-native/Libraries/Image/__tests__/Image-requestPriority-itest.js b/packages/react-native/Libraries/Image/__tests__/Image-requestPriority-itest.js deleted file mode 100644 index ae6a64f0977c..000000000000 --- a/packages/react-native/Libraries/Image/__tests__/Image-requestPriority-itest.js +++ /dev/null @@ -1,455 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @fantom_flags enableImageRequestDowngradingForNonVisibleImages:true - * @flow strict-local - * @format - */ - -import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; - -import type {RootConfig} from '@react-native/fantom'; - -import * as Fantom from '@react-native/fantom'; -import * as React from 'react'; -import {Image, ScrollView, View} from 'react-native'; -import NativeFantom from 'react-native/src/private/testing/fantom/specs/NativeFantom'; - -const IMAGE_SOURCE = {uri: 'https://reactnative.dev/img/tiny_logo.png'}; -const UPDATED_IMAGE_SOURCE = { - uri: 'https://reactnative.dev/img/header_logo.svg', -}; - -type ImageRequestPriority = 'immediate' | 'prefetch'; - -function expectLatestImageRequestPriority( - element: React.MixedElement, - expectedPriority: ImageRequestPriority, - rootConfig?: RootConfig, -) { - const root = Fantom.createRoot({ - viewportWidth: 100, - viewportHeight: 100, - ...rootConfig, - }); - - Fantom.runTask(() => { - root.render(element); - }); - - expect(NativeFantom.getImageRequestCount(IMAGE_SOURCE.uri)).toBe(1); - expect(NativeFantom.getImageRequestPriority(IMAGE_SOURCE.uri)).toBe( - expectedPriority, - ); -} - -describe(' request priority', () => { - beforeEach(() => { - NativeFantom.clearImageRequests(); - }); - - afterEach(() => { - NativeFantom.clearImageRequests(); - }); - - it('requests visible images at immediate priority', () => { - expectLatestImageRequestPriority( - , - 'immediate', - ); - }); - - it('requests images below the viewport at prefetch priority', () => { - expectLatestImageRequestPriority( - , - 'prefetch', - ); - }); - - it('requests images above the viewport at prefetch priority', () => { - expectLatestImageRequestPriority( - , - 'prefetch', - ); - }); - - it('requests images left of the viewport at prefetch priority', () => { - expectLatestImageRequestPriority( - , - 'prefetch', - ); - }); - - it('requests images right of the viewport at prefetch priority', () => { - expectLatestImageRequestPriority( - , - 'prefetch', - ); - }); - - it('requests edge-touching images at prefetch priority', () => { - expectLatestImageRequestPriority( - , - 'prefetch', - ); - }); - - it('requests one-pixel-overlapping images at immediate priority', () => { - expectLatestImageRequestPriority( - , - 'immediate', - ); - }); - - it('uses nested layout offsets when calculating priority', () => { - expectLatestImageRequestPriority( - - - , - 'prefetch', - ); - }); - - it('uses viewport offsets when calculating priority', () => { - expectLatestImageRequestPriority( - , - 'prefetch', - { - viewportOffsetY: 25, - }, - ); - }); - - it('uses ScrollView content offsets when calculating priority', () => { - expectLatestImageRequestPriority( - - - , - 'immediate', - ); - }); - - it('requests images above the ScrollView viewport at prefetch priority', () => { - expectLatestImageRequestPriority( - - - , - 'prefetch', - ); - }); - - it('requests images below the ScrollView viewport at prefetch priority', () => { - expectLatestImageRequestPriority( - - - , - 'prefetch', - ); - }); - - it('uses smaller ScrollView content offsets when calculating priority', () => { - expectLatestImageRequestPriority( - - - , - 'immediate', - ); - }); - - it('uses horizontal ScrollView content offsets when calculating priority', () => { - expectLatestImageRequestPriority( - - - , - 'immediate', - ); - }); - - it('requests images left of a horizontal ScrollView viewport at prefetch priority', () => { - expectLatestImageRequestPriority( - - - , - 'prefetch', - ); - }); - - it('requests images right of a horizontal ScrollView viewport at prefetch priority', () => { - expectLatestImageRequestPriority( - - - , - 'prefetch', - ); - }); - - it('uses image transforms when calculating priority', () => { - expectLatestImageRequestPriority( - , - 'immediate', - ); - }); - - it('uses image transforms that move images out of the viewport when calculating priority', () => { - expectLatestImageRequestPriority( - , - 'prefetch', - ); - }); - - it('uses image scale transforms when calculating priority', () => { - expectLatestImageRequestPriority( - , - 'immediate', - ); - }); - - it('uses ancestor transforms when calculating priority', () => { - expectLatestImageRequestPriority( - - - , - 'immediate', - ); - }); - - it('uses ancestor transforms that move images out of the viewport when calculating priority', () => { - expectLatestImageRequestPriority( - - - , - 'prefetch', - ); - }); - - it('updates priority when layout moves an image onscreen', () => { - const root = Fantom.createRoot({ - viewportWidth: 100, - viewportHeight: 100, - }); - - Fantom.runTask(() => { - root.render( - , - ); - }); - - expect(NativeFantom.getImageRequestCount(IMAGE_SOURCE.uri)).toBe(1); - expect(NativeFantom.getImageRequestPriority(IMAGE_SOURCE.uri)).toBe( - 'prefetch', - ); - - Fantom.runTask(() => { - root.render( - , - ); - }); - - expect(NativeFantom.getImageRequestCount(IMAGE_SOURCE.uri)).toBe(2); - expect(NativeFantom.getImageRequestPriority(IMAGE_SOURCE.uri)).toBe( - 'immediate', - ); - }); - - it('keeps offscreen priority when the source changes without a layout change', () => { - const root = Fantom.createRoot({ - viewportWidth: 100, - viewportHeight: 100, - }); - - const offscreenStyle = { - height: 50, - left: 0, - position: 'absolute', - top: 150, - width: 50, - } as const; - - Fantom.runTask(() => { - root.render(); - }); - - expect(NativeFantom.getImageRequestCount(IMAGE_SOURCE.uri)).toBe(1); - expect(NativeFantom.getImageRequestPriority(IMAGE_SOURCE.uri)).toBe( - 'prefetch', - ); - - NativeFantom.clearImageRequests(); - - Fantom.runTask(() => { - root.render( - , - ); - }); - - expect(NativeFantom.getImageRequestCount(UPDATED_IMAGE_SOURCE.uri)).toBe(1); - expect(NativeFantom.getImageRequestPriority(UPDATED_IMAGE_SOURCE.uri)).toBe( - 'prefetch', - ); - }); -}); diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm index 8f60235ca3b6..99104f0ec8fc 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm @@ -11,7 +11,6 @@ #import #import #import -#import #import #import #import @@ -20,40 +19,9 @@ using namespace facebook::react; -static NSString *const RCTImageRequestPriorityDebugOverlayEnabledEnvironmentVariable = - @"RCT_IMAGE_REQUEST_PRIORITY_DEBUG_OVERLAY"; - -static BOOL RCTImageRequestPriorityDebugOverlayEnabled() -{ - if (ReactNativeFeatureFlags::enableImageRequestDowngradingForNonVisibleImages()) { - static BOOL enabled = NO; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSDictionary *environment = [[NSProcessInfo processInfo] environment]; - enabled = [environment[RCTImageRequestPriorityDebugOverlayEnabledEnvironmentVariable] boolValue]; - }); - return enabled; - } else { - return NO; - } -} - -static NSString *RCTImageRequestPriorityDebugLabel(ImageRequestPriority priority) -{ - switch (priority) { - case ImageRequestPriority::Immediate: - return @"immediate"; - case ImageRequestPriority::Prefetch: - return @"offscreen"; - default: - return @"unknown"; - } -} - @implementation RCTImageComponentView { ImageShadowNode::ConcreteState::Shared _state; std::shared_ptr _imageResponseObserverProxy; - UILabel *_requestPriorityLabel; } - (instancetype)initWithFrame:(CGRect)frame @@ -117,7 +85,6 @@ - (void)updateState:(const State::Shared &)state oldState:(const State::Shared & auto newImageState = std::static_pointer_cast(state); [self _setStateAndResubscribeImageResponseObserver:newImageState]; - [self _updateRequestPriorityLabelWithState:newImageState]; bool havePreviousData = oldImageState && oldImageState->getData().getImageSource() != ImageSource{}; @@ -148,53 +115,10 @@ - (void)_setStateAndResubscribeImageResponseObserver:(const ImageShadowNode::Con } } -- (UILabel *)_requestPriorityLabel -{ - if (!_requestPriorityLabel) { - _requestPriorityLabel = [UILabel new]; - _requestPriorityLabel.accessibilityElementsHidden = YES; - _requestPriorityLabel.backgroundColor = [UIColor colorWithWhite:0 alpha:0.65]; - _requestPriorityLabel.clipsToBounds = YES; - _requestPriorityLabel.font = [UIFont systemFontOfSize:10 weight:UIFontWeightSemibold]; - _requestPriorityLabel.hidden = YES; - _requestPriorityLabel.isAccessibilityElement = NO; - _requestPriorityLabel.layer.cornerRadius = 3; - _requestPriorityLabel.textAlignment = NSTextAlignmentCenter; - _requestPriorityLabel.textColor = UIColor.whiteColor; - [_imageView addSubview:_requestPriorityLabel]; - } - - return _requestPriorityLabel; -} - -- (void)_updateRequestPriorityLabelWithState:(const ImageShadowNode::ConcreteState::Shared &)state -{ - if (!state || !RCTImageRequestPriorityDebugOverlayEnabled()) { - if (_requestPriorityLabel) { - _requestPriorityLabel.hidden = YES; - _requestPriorityLabel.text = nil; - } - return; - } - - UILabel *requestPriorityLabel = [self _requestPriorityLabel]; - requestPriorityLabel.text = RCTImageRequestPriorityDebugLabel(state->getData().getImageRequestParams().priority); - [requestPriorityLabel sizeToFit]; - - CGRect frame = requestPriorityLabel.frame; - frame.origin = CGPointMake(2, 2); - frame.size.width += 8; - frame.size.height += 4; - requestPriorityLabel.frame = frame; - requestPriorityLabel.hidden = NO; - [_imageView bringSubviewToFront:requestPriorityLabel]; -} - - (void)prepareForRecycle { [super prepareForRecycle]; [self _setStateAndResubscribeImageResponseObserver:nullptr]; - [self _updateRequestPriorityLabelWithState:nullptr]; _imageView.image = nil; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 997717fe9055..868600367575 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -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<> + * @generated SignedSource<<00bb39539f4fc2dc0ad85a346bdee22b>> */ /** @@ -192,12 +192,6 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableImagePrefetchingAndroid(): Boolean = accessor.enableImagePrefetchingAndroid() - /** - * When enabled, ImageShadowNode downgrades image requests to prefetch priority when layout determines that the image does not intersect the viewport. - */ - @JvmStatic - public fun enableImageRequestDowngradingForNonVisibleImages(): Boolean = accessor.enableImageRequestDowngradingForNonVisibleImages() - /** * Dispatches state updates for content offset changes synchronously on the main thread. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index d6cfca387018..a6e2a21f33c6 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -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<<5bf52aa57fc011858db9f632930bb8fb>> + * @generated SignedSource<<731e92ecac8dbdf0a4b204b763a2c8c7>> */ /** @@ -47,7 +47,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var enableIOSTextBaselineOffsetPerLineCache: Boolean? = null private var enableIOSViewClipToPaddingBoxCache: Boolean? = null private var enableImagePrefetchingAndroidCache: Boolean? = null - private var enableImageRequestDowngradingForNonVisibleImagesCache: Boolean? = null private var enableImmediateUpdateModeForContentOffsetChangesCache: Boolean? = null private var enableImperativeFocusCache: Boolean? = null private var enableInteropViewManagerClassLookUpOptimizationIOSCache: Boolean? = null @@ -349,15 +348,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun enableImageRequestDowngradingForNonVisibleImages(): Boolean { - var cached = enableImageRequestDowngradingForNonVisibleImagesCache - if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.enableImageRequestDowngradingForNonVisibleImages() - enableImageRequestDowngradingForNonVisibleImagesCache = cached - } - return cached - } - override fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean { var cached = enableImmediateUpdateModeForContentOffsetChangesCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index f43d355cfb17..59fa21d68da9 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -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<<4c03e1b03360e7703ffd1d7aa0afc277>> + * @generated SignedSource<<4d0952ded695aec4a52b7b581ad19979>> */ /** @@ -82,8 +82,6 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableImagePrefetchingAndroid(): Boolean - @DoNotStrip @JvmStatic public external fun enableImageRequestDowngradingForNonVisibleImages(): Boolean - @DoNotStrip @JvmStatic public external fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean @DoNotStrip @JvmStatic public external fun enableImperativeFocus(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index 9e708427b7df..3c3615871526 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -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<<0dcc15b419f6805bdbeec4727ad94761>> + * @generated SignedSource<<4c0b09eb9df8e4580dc4778a91591236>> */ /** @@ -77,8 +77,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableImagePrefetchingAndroid(): Boolean = false - override fun enableImageRequestDowngradingForNonVisibleImages(): Boolean = false - override fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean = false override fun enableImperativeFocus(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 8dbf083ab9b7..114ad7a526ea 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -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<> + * @generated SignedSource<<156af11c13257170355284118e400435>> */ /** @@ -51,7 +51,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var enableIOSTextBaselineOffsetPerLineCache: Boolean? = null private var enableIOSViewClipToPaddingBoxCache: Boolean? = null private var enableImagePrefetchingAndroidCache: Boolean? = null - private var enableImageRequestDowngradingForNonVisibleImagesCache: Boolean? = null private var enableImmediateUpdateModeForContentOffsetChangesCache: Boolean? = null private var enableImperativeFocusCache: Boolean? = null private var enableInteropViewManagerClassLookUpOptimizationIOSCache: Boolean? = null @@ -380,16 +379,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } - override fun enableImageRequestDowngradingForNonVisibleImages(): Boolean { - var cached = enableImageRequestDowngradingForNonVisibleImagesCache - if (cached == null) { - cached = currentProvider.enableImageRequestDowngradingForNonVisibleImages() - accessedFeatureFlags.add("enableImageRequestDowngradingForNonVisibleImages") - enableImageRequestDowngradingForNonVisibleImagesCache = cached - } - return cached - } - override fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean { var cached = enableImmediateUpdateModeForContentOffsetChangesCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 8855e869f5b5..8908aaf3a057 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -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<<4f18bde7c0680691cd6fceb63c41ad65>> + * @generated SignedSource<> */ /** @@ -77,8 +77,6 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableImagePrefetchingAndroid(): Boolean - @DoNotStrip public fun enableImageRequestDowngradingForNonVisibleImages(): Boolean - @DoNotStrip public fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean @DoNotStrip public fun enableImperativeFocus(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index bf7907626ecb..d99ee6ee4f35 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -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<<13e7b6ef510a97b4210de914a015ae11>> + * @generated SignedSource<<671da9c60f7c7331ece553327ee3ab33>> */ /** @@ -201,12 +201,6 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } - bool enableImageRequestDowngradingForNonVisibleImages() override { - static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableImageRequestDowngradingForNonVisibleImages"); - return method(javaProvider_); - } - bool enableImmediateUpdateModeForContentOffsetChanges() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableImmediateUpdateModeForContentOffsetChanges"); @@ -688,11 +682,6 @@ bool JReactNativeFeatureFlagsCxxInterop::enableImagePrefetchingAndroid( return ReactNativeFeatureFlags::enableImagePrefetchingAndroid(); } -bool JReactNativeFeatureFlagsCxxInterop::enableImageRequestDowngradingForNonVisibleImages( - facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::enableImageRequestDowngradingForNonVisibleImages(); -} - bool JReactNativeFeatureFlagsCxxInterop::enableImmediateUpdateModeForContentOffsetChanges( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges(); @@ -1090,9 +1079,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableImagePrefetchingAndroid", JReactNativeFeatureFlagsCxxInterop::enableImagePrefetchingAndroid), - makeNativeMethod( - "enableImageRequestDowngradingForNonVisibleImages", - JReactNativeFeatureFlagsCxxInterop::enableImageRequestDowngradingForNonVisibleImages), makeNativeMethod( "enableImmediateUpdateModeForContentOffsetChanges", JReactNativeFeatureFlagsCxxInterop::enableImmediateUpdateModeForContentOffsetChanges), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index a8a0831561ab..a6feb96ac72f 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -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<<4234522fd98acef7836d8050d0e7c82d>> + * @generated SignedSource<> */ /** @@ -111,9 +111,6 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableImagePrefetchingAndroid( facebook::jni::alias_ref); - static bool enableImageRequestDowngradingForNonVisibleImages( - facebook::jni::alias_ref); - static bool enableImmediateUpdateModeForContentOffsetChanges( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index a0227722197a..afd20ad674bc 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -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<<0bafa89fa8781cb3c7aebf5d0bb8678e>> + * @generated SignedSource<<57f84b7025cf1fc77f5f99dfc4653fb4>> */ /** @@ -134,10 +134,6 @@ bool ReactNativeFeatureFlags::enableImagePrefetchingAndroid() { return getAccessor().enableImagePrefetchingAndroid(); } -bool ReactNativeFeatureFlags::enableImageRequestDowngradingForNonVisibleImages() { - return getAccessor().enableImageRequestDowngradingForNonVisibleImages(); -} - bool ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges() { return getAccessor().enableImmediateUpdateModeForContentOffsetChanges(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index f00873e7700b..8761e43346ba 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -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<<3fca574dc84a346c113e479d0583537c>> + * @generated SignedSource<> */ /** @@ -174,11 +174,6 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableImagePrefetchingAndroid(); - /** - * When enabled, ImageShadowNode downgrades image requests to prefetch priority when layout determines that the image does not intersect the viewport. - */ - RN_EXPORT static bool enableImageRequestDowngradingForNonVisibleImages(); - /** * Dispatches state updates for content offset changes synchronously on the main thread. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 5d234f7446f7..f0c2e39839b4 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -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<<1ee65c6b449518e6ae582aa61effa2e3>> + * @generated SignedSource<<3effa01ecbf45e028b9268195920178b>> */ /** @@ -515,24 +515,6 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingAndroid() { return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::enableImageRequestDowngradingForNonVisibleImages() { - auto flagValue = enableImageRequestDowngradingForNonVisibleImages_.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(27, "enableImageRequestDowngradingForNonVisibleImages"); - - flagValue = currentProvider_->enableImageRequestDowngradingForNonVisibleImages(); - enableImageRequestDowngradingForNonVisibleImages_ = flagValue; - } - - return flagValue.value(); -} - bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetChanges() { auto flagValue = enableImmediateUpdateModeForContentOffsetChanges_.load(); @@ -542,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetC // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "enableImmediateUpdateModeForContentOffsetChanges"); + markFlagAsAccessed(27, "enableImmediateUpdateModeForContentOffsetChanges"); flagValue = currentProvider_->enableImmediateUpdateModeForContentOffsetChanges(); enableImmediateUpdateModeForContentOffsetChanges_ = flagValue; @@ -560,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImperativeFocus() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "enableImperativeFocus"); + markFlagAsAccessed(28, "enableImperativeFocus"); flagValue = currentProvider_->enableImperativeFocus(); enableImperativeFocus_ = flagValue; @@ -578,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::enableInteropViewManagerClassLookUpOptimiz // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "enableInteropViewManagerClassLookUpOptimizationIOS"); + markFlagAsAccessed(29, "enableInteropViewManagerClassLookUpOptimizationIOS"); flagValue = currentProvider_->enableInteropViewManagerClassLookUpOptimizationIOS(); enableInteropViewManagerClassLookUpOptimizationIOS_ = flagValue; @@ -596,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIntersectionObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "enableIntersectionObserverByDefault"); + markFlagAsAccessed(30, "enableIntersectionObserverByDefault"); flagValue = currentProvider_->enableIntersectionObserverByDefault(); enableIntersectionObserverByDefault_ = flagValue; @@ -614,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::enableKeyEvents() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "enableKeyEvents"); + markFlagAsAccessed(31, "enableKeyEvents"); flagValue = currentProvider_->enableKeyEvents(); enableKeyEvents_ = flagValue; @@ -632,7 +614,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(33, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(32, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -650,7 +632,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(34, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(33, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -668,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::enableModuleArgumentNSNullConversionIOS() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "enableModuleArgumentNSNullConversionIOS"); + markFlagAsAccessed(34, "enableModuleArgumentNSNullConversionIOS"); flagValue = currentProvider_->enableModuleArgumentNSNullConversionIOS(); enableModuleArgumentNSNullConversionIOS_ = flagValue; @@ -686,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMutationObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "enableMutationObserverByDefault"); + markFlagAsAccessed(35, "enableMutationObserverByDefault"); flagValue = currentProvider_->enableMutationObserverByDefault(); enableMutationObserverByDefault_ = flagValue; @@ -704,7 +686,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(37, "enableNativeCSSParsing"); + markFlagAsAccessed(36, "enableNativeCSSParsing"); flagValue = currentProvider_->enableNativeCSSParsing(); enableNativeCSSParsing_ = flagValue; @@ -722,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNetworkEventReporting() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "enableNetworkEventReporting"); + markFlagAsAccessed(37, "enableNetworkEventReporting"); flagValue = currentProvider_->enableNetworkEventReporting(); enableNetworkEventReporting_ = flagValue; @@ -740,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreparedTextLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "enablePreparedTextLayout"); + markFlagAsAccessed(38, "enablePreparedTextLayout"); flagValue = currentProvider_->enablePreparedTextLayout(); enablePreparedTextLayout_ = flagValue; @@ -758,7 +740,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(40, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(39, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -776,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::enableRuntimeSchedulerQueueClearingOnError // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "enableRuntimeSchedulerQueueClearingOnError"); + markFlagAsAccessed(40, "enableRuntimeSchedulerQueueClearingOnError"); flagValue = currentProvider_->enableRuntimeSchedulerQueueClearingOnError(); enableRuntimeSchedulerQueueClearingOnError_ = flagValue; @@ -794,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSchedulerDelegateInvalidation() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "enableSchedulerDelegateInvalidation"); + markFlagAsAccessed(41, "enableSchedulerDelegateInvalidation"); flagValue = currentProvider_->enableSchedulerDelegateInvalidation(); enableSchedulerDelegateInvalidation_ = flagValue; @@ -812,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSwiftUIBasedFilters() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "enableSwiftUIBasedFilters"); + markFlagAsAccessed(42, "enableSwiftUIBasedFilters"); flagValue = currentProvider_->enableSwiftUIBasedFilters(); enableSwiftUIBasedFilters_ = flagValue; @@ -830,7 +812,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(44, "enableViewCulling"); + markFlagAsAccessed(43, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -848,7 +830,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(45, "enableViewRecycling"); + markFlagAsAccessed(44, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -866,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForImage() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "enableViewRecyclingForImage"); + markFlagAsAccessed(45, "enableViewRecyclingForImage"); flagValue = currentProvider_->enableViewRecyclingForImage(); enableViewRecyclingForImage_ = flagValue; @@ -884,7 +866,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForScrollView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "enableViewRecyclingForScrollView"); + markFlagAsAccessed(46, "enableViewRecyclingForScrollView"); flagValue = currentProvider_->enableViewRecyclingForScrollView(); enableViewRecyclingForScrollView_ = flagValue; @@ -902,7 +884,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(48, "enableViewRecyclingForText"); + markFlagAsAccessed(47, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -920,7 +902,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(49, "enableViewRecyclingForView"); + markFlagAsAccessed(48, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -938,7 +920,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewContainerStateExperimenta // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(50, "enableVirtualViewContainerStateExperimental"); + markFlagAsAccessed(49, "enableVirtualViewContainerStateExperimental"); flagValue = currentProvider_->enableVirtualViewContainerStateExperimental(); enableVirtualViewContainerStateExperimental_ = flagValue; @@ -956,7 +938,7 @@ bool ReactNativeFeatureFlagsAccessor::fixDifferentiatorParentTagForUnflattenCase // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(51, "fixDifferentiatorParentTagForUnflattenCase"); + markFlagAsAccessed(50, "fixDifferentiatorParentTagForUnflattenCase"); flagValue = currentProvider_->fixDifferentiatorParentTagForUnflattenCase(); fixDifferentiatorParentTagForUnflattenCase_ = flagValue; @@ -974,7 +956,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(52, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(51, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -992,7 +974,7 @@ bool ReactNativeFeatureFlagsAccessor::fixYogaFlexBasisFitContentInMainAxis() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(53, "fixYogaFlexBasisFitContentInMainAxis"); + markFlagAsAccessed(52, "fixYogaFlexBasisFitContentInMainAxis"); flagValue = currentProvider_->fixYogaFlexBasisFitContentInMainAxis(); fixYogaFlexBasisFitContentInMainAxis_ = flagValue; @@ -1010,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxAssertSingleHostState() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(54, "fuseboxAssertSingleHostState"); + markFlagAsAccessed(53, "fuseboxAssertSingleHostState"); flagValue = currentProvider_->fuseboxAssertSingleHostState(); fuseboxAssertSingleHostState_ = flagValue; @@ -1028,7 +1010,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(55, "fuseboxEnabledRelease"); + markFlagAsAccessed(54, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -1046,7 +1028,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxFrameRecordingEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(56, "fuseboxFrameRecordingEnabled"); + markFlagAsAccessed(55, "fuseboxFrameRecordingEnabled"); flagValue = currentProvider_->fuseboxFrameRecordingEnabled(); fuseboxFrameRecordingEnabled_ = flagValue; @@ -1064,7 +1046,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(57, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(56, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -1082,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxScreenshotCaptureEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(58, "fuseboxScreenshotCaptureEnabled"); + markFlagAsAccessed(57, "fuseboxScreenshotCaptureEnabled"); flagValue = currentProvider_->fuseboxScreenshotCaptureEnabled(); fuseboxScreenshotCaptureEnabled_ = flagValue; @@ -1100,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::optimizedAnimatedPropUpdates() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(59, "optimizedAnimatedPropUpdates"); + markFlagAsAccessed(58, "optimizedAnimatedPropUpdates"); flagValue = currentProvider_->optimizedAnimatedPropUpdates(); optimizedAnimatedPropUpdates_ = flagValue; @@ -1118,7 +1100,7 @@ bool ReactNativeFeatureFlagsAccessor::overrideBySynchronousMountPropsAtMountingA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(60, "overrideBySynchronousMountPropsAtMountingAndroid"); + markFlagAsAccessed(59, "overrideBySynchronousMountPropsAtMountingAndroid"); flagValue = currentProvider_->overrideBySynchronousMountPropsAtMountingAndroid(); overrideBySynchronousMountPropsAtMountingAndroid_ = flagValue; @@ -1136,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::perfIssuesEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(61, "perfIssuesEnabled"); + markFlagAsAccessed(60, "perfIssuesEnabled"); flagValue = currentProvider_->perfIssuesEnabled(); perfIssuesEnabled_ = flagValue; @@ -1154,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::perfMonitorV2Enabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(62, "perfMonitorV2Enabled"); + markFlagAsAccessed(61, "perfMonitorV2Enabled"); flagValue = currentProvider_->perfMonitorV2Enabled(); perfMonitorV2Enabled_ = flagValue; @@ -1172,7 +1154,7 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(63, "preparedTextCacheSize"); + markFlagAsAccessed(62, "preparedTextCacheSize"); flagValue = currentProvider_->preparedTextCacheSize(); preparedTextCacheSize_ = flagValue; @@ -1190,7 +1172,7 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(64, "preventShadowTreeCommitExhaustion"); + markFlagAsAccessed(63, "preventShadowTreeCommitExhaustion"); flagValue = currentProvider_->preventShadowTreeCommitExhaustion(); preventShadowTreeCommitExhaustion_ = flagValue; @@ -1208,7 +1190,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2Android() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(65, "redBoxV2Android"); + markFlagAsAccessed(64, "redBoxV2Android"); flagValue = currentProvider_->redBoxV2Android(); redBoxV2Android_ = flagValue; @@ -1226,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2IOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(66, "redBoxV2IOS"); + markFlagAsAccessed(65, "redBoxV2IOS"); flagValue = currentProvider_->redBoxV2IOS(); redBoxV2IOS_ = flagValue; @@ -1244,7 +1226,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(67, "shouldPressibilityUseW3CPointerEventsForHover"); + markFlagAsAccessed(66, "shouldPressibilityUseW3CPointerEventsForHover"); flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover(); shouldPressibilityUseW3CPointerEventsForHover_ = flagValue; @@ -1262,7 +1244,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldTriggerResponderTransferOnScrollAndr // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(68, "shouldTriggerResponderTransferOnScrollAndroid"); + markFlagAsAccessed(67, "shouldTriggerResponderTransferOnScrollAndroid"); flagValue = currentProvider_->shouldTriggerResponderTransferOnScrollAndroid(); shouldTriggerResponderTransferOnScrollAndroid_ = flagValue; @@ -1280,7 +1262,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(69, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(68, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -1298,7 +1280,7 @@ bool ReactNativeFeatureFlagsAccessor::syncAndroidClipBoundsWithOverflow() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(70, "syncAndroidClipBoundsWithOverflow"); + markFlagAsAccessed(69, "syncAndroidClipBoundsWithOverflow"); flagValue = currentProvider_->syncAndroidClipBoundsWithOverflow(); syncAndroidClipBoundsWithOverflow_ = flagValue; @@ -1316,7 +1298,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(71, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(70, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -1334,7 +1316,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(72, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(71, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -1352,7 +1334,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommitT // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(73, "updateRuntimeShadowNodeReferencesOnCommitThread"); + markFlagAsAccessed(72, "updateRuntimeShadowNodeReferencesOnCommitThread"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommitThread(); updateRuntimeShadowNodeReferencesOnCommitThread_ = flagValue; @@ -1370,7 +1352,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(74, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(73, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1388,7 +1370,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(75, "useFabricInterop"); + markFlagAsAccessed(74, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1406,7 +1388,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(76, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(75, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1424,7 +1406,7 @@ bool ReactNativeFeatureFlagsAccessor::useNestedScrollViewAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(77, "useNestedScrollViewAndroid"); + markFlagAsAccessed(76, "useNestedScrollViewAndroid"); flagValue = currentProvider_->useNestedScrollViewAndroid(); useNestedScrollViewAndroid_ = flagValue; @@ -1442,7 +1424,7 @@ bool ReactNativeFeatureFlagsAccessor::useSharedAnimatedBackend() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(78, "useSharedAnimatedBackend"); + markFlagAsAccessed(77, "useSharedAnimatedBackend"); flagValue = currentProvider_->useSharedAnimatedBackend(); useSharedAnimatedBackend_ = flagValue; @@ -1460,7 +1442,7 @@ bool ReactNativeFeatureFlagsAccessor::useTraitHiddenOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(79, "useTraitHiddenOnAndroid"); + markFlagAsAccessed(78, "useTraitHiddenOnAndroid"); flagValue = currentProvider_->useTraitHiddenOnAndroid(); useTraitHiddenOnAndroid_ = flagValue; @@ -1478,7 +1460,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(80, "useTurboModuleInterop"); + markFlagAsAccessed(79, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1496,7 +1478,7 @@ double ReactNativeFeatureFlagsAccessor::viewCullingOutsetRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(81, "viewCullingOutsetRatio"); + markFlagAsAccessed(80, "viewCullingOutsetRatio"); flagValue = currentProvider_->viewCullingOutsetRatio(); viewCullingOutsetRatio_ = flagValue; @@ -1514,7 +1496,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(82, "viewTransitionEnabled"); + markFlagAsAccessed(81, "viewTransitionEnabled"); flagValue = currentProvider_->viewTransitionEnabled(); viewTransitionEnabled_ = flagValue; @@ -1532,7 +1514,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionUseHardwareBitmapAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(83, "viewTransitionUseHardwareBitmapAndroid"); + markFlagAsAccessed(82, "viewTransitionUseHardwareBitmapAndroid"); flagValue = currentProvider_->viewTransitionUseHardwareBitmapAndroid(); viewTransitionUseHardwareBitmapAndroid_ = flagValue; @@ -1550,7 +1532,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(84, "virtualViewPrerenderRatio"); + markFlagAsAccessed(83, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index c5419463dd3c..485fc0276531 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -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<<80fcb1756caccd2259335a67984d76d5>> + * @generated SignedSource<> */ /** @@ -59,7 +59,6 @@ class ReactNativeFeatureFlagsAccessor { bool enableIOSTextBaselineOffsetPerLine(); bool enableIOSViewClipToPaddingBox(); bool enableImagePrefetchingAndroid(); - bool enableImageRequestDowngradingForNonVisibleImages(); bool enableImmediateUpdateModeForContentOffsetChanges(); bool enableImperativeFocus(); bool enableInteropViewManagerClassLookUpOptimizationIOS(); @@ -128,7 +127,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 85> accessedFeatureFlags_; + std::array, 84> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -157,7 +156,6 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableIOSTextBaselineOffsetPerLine_; std::atomic> enableIOSViewClipToPaddingBox_; std::atomic> enableImagePrefetchingAndroid_; - std::atomic> enableImageRequestDowngradingForNonVisibleImages_; std::atomic> enableImmediateUpdateModeForContentOffsetChanges_; std::atomic> enableImperativeFocus_; std::atomic> enableInteropViewManagerClassLookUpOptimizationIOS_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 89637fbde8dd..f42230f27078 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -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<<613be235a200f15ac2ec48d1f5d87053>> + * @generated SignedSource<<6451b9c50b78b3b00fc74b137f5ca541>> */ /** @@ -135,10 +135,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } - bool enableImageRequestDowngradingForNonVisibleImages() override { - return false; - } - bool enableImmediateUpdateModeForContentOffsetChanges() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index a2e10dda1703..d01628a0839c 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -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<<215e8b28994854f31f249a5e51623c87>> + * @generated SignedSource<> */ /** @@ -288,15 +288,6 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::enableImagePrefetchingAndroid(); } - bool enableImageRequestDowngradingForNonVisibleImages() override { - auto value = values_["enableImageRequestDowngradingForNonVisibleImages"]; - if (!value.isNull()) { - return value.getBool(); - } - - return ReactNativeFeatureFlagsDefaults::enableImageRequestDowngradingForNonVisibleImages(); - } - bool enableImmediateUpdateModeForContentOffsetChanges() override { auto value = values_["enableImmediateUpdateModeForContentOffsetChanges"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index aac79cc9f568..b9911886579f 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -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<> + * @generated SignedSource<<928b5ecbceacccae311edf4be6685c91>> */ /** @@ -52,7 +52,6 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableIOSTextBaselineOffsetPerLine() = 0; virtual bool enableIOSViewClipToPaddingBox() = 0; virtual bool enableImagePrefetchingAndroid() = 0; - virtual bool enableImageRequestDowngradingForNonVisibleImages() = 0; virtual bool enableImmediateUpdateModeForContentOffsetChanges() = 0; virtual bool enableImperativeFocus() = 0; virtual bool enableInteropViewManagerClassLookUpOptimizationIOS() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 594d3c9d7b1b..e566499b25f9 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -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<> + * @generated SignedSource<<84ae8c7745f319878c329e07551bcc11>> */ /** @@ -179,11 +179,6 @@ bool NativeReactNativeFeatureFlags::enableImagePrefetchingAndroid( return ReactNativeFeatureFlags::enableImagePrefetchingAndroid(); } -bool NativeReactNativeFeatureFlags::enableImageRequestDowngradingForNonVisibleImages( - jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::enableImageRequestDowngradingForNonVisibleImages(); -} - bool NativeReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index b5ddcd8a969f..ff722eb7e57b 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -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<<92d22193e04fdbd6cfb119d69496c065>> + * @generated SignedSource<<19abe441594bf45b32c5c9cdcd9ca8d4>> */ /** @@ -90,8 +90,6 @@ class NativeReactNativeFeatureFlags bool enableImagePrefetchingAndroid(jsi::Runtime& runtime); - bool enableImageRequestDowngradingForNonVisibleImages(jsi::Runtime& runtime); - bool enableImmediateUpdateModeForContentOffsetChanges(jsi::Runtime& runtime); bool enableImperativeFocus(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/components/image/ImageShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/image/ImageShadowNode.cpp index 1b05a1a4cedd..caea0e5fe5fe 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/image/ImageShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/image/ImageShadowNode.cpp @@ -13,49 +13,12 @@ #include #include #include -#include #include namespace facebook::react { const char ImageComponentName[] = "Image"; -namespace { - -bool isImageVisible( - const LayoutContext& layoutContext, - const LayoutMetrics& layoutMetrics) { - if (layoutContext.viewportSize.width <= 0 || - layoutContext.viewportSize.height <= 0 || - layoutMetrics.frame.size.width <= 0 || - layoutMetrics.frame.size.height <= 0) { - return true; - } - - auto imageFrame = layoutContext.experimental_layoutFrame; - if (imageFrame.size.width <= 0 || imageFrame.size.height <= 0) { - imageFrame = Rect{ - .origin = layoutContext.experimental_layoutOrigin, - .size = layoutMetrics.frame.size}; - } - auto viewportFrame = Rect{ - .origin = layoutContext.viewportOffset, - .size = layoutContext.viewportSize}; - auto visibleFrame = Rect::intersect(imageFrame, viewportFrame); - - return visibleFrame.size.width > 0 && visibleFrame.size.height > 0; -} - -ImageRequestPriority getImageRequestPriority( - const LayoutContext& layoutContext, - const LayoutMetrics& layoutMetrics) { - return isImageVisible(layoutContext, layoutMetrics) - ? ImageRequestPriority::Immediate - : ImageRequestPriority::Prefetch; -} - -} // namespace - void ImageShadowNode::setImageManager( const std::shared_ptr& imageManager) { ensureUnsealed(); @@ -74,16 +37,12 @@ void ImageShadowNode::setImageManager( if (sources.size() <= 1 || (layoutMetric.frame.size.width > 0 && layoutMetric.frame.size.height > 0)) { - auto priority = ReactNativeFeatureFlags:: - enableImageRequestDowngradingForNonVisibleImages() - ? getStateData().getImageRequestParams().priority - : ImageRequestPriority::Immediate; - updateStateIfNeeded(priority); + updateStateIfNeeded(); } } } -void ImageShadowNode::updateStateIfNeeded(ImageRequestPriority priority) { +void ImageShadowNode::updateStateIfNeeded() { ensureUnsealed(); const auto& savedState = getStateData(); @@ -112,9 +71,6 @@ void ImageShadowNode::updateStateIfNeeded(ImageRequestPriority priority) { layoutMetrics_.frame.size.width * layoutMetrics_.pointScaleFactor, .height = layoutMetrics_.frame.size.height * layoutMetrics_.pointScaleFactor} -#else - , - priority #endif ); @@ -199,12 +155,7 @@ ImageSource ImageShadowNode::getImageSource() const { #pragma mark - LayoutableShadowNode void ImageShadowNode::layout(LayoutContext layoutContext) { - auto imageRequestPriority = - ReactNativeFeatureFlags:: - enableImageRequestDowngradingForNonVisibleImages() - ? getImageRequestPriority(layoutContext, getLayoutMetrics()) - : ImageRequestPriority::Immediate; - updateStateIfNeeded(imageRequestPriority); + updateStateIfNeeded(); ConcreteViewShadowNode::layout(layoutContext); } diff --git a/packages/react-native/ReactCommon/react/renderer/components/image/ImageShadowNode.h b/packages/react-native/ReactCommon/react/renderer/components/image/ImageShadowNode.h index d5e0f817913d..3ecd4672d12d 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/image/ImageShadowNode.h +++ b/packages/react-native/ReactCommon/react/renderer/components/image/ImageShadowNode.h @@ -57,7 +57,7 @@ class ImageShadowNode final std::shared_ptr imageManager_; - void updateStateIfNeeded(ImageRequestPriority priority); + void updateStateIfNeeded(); }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp index 07f251da88cd..fb72421213ab 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp @@ -697,13 +697,6 @@ void YogaLayoutableShadowNode::layoutTree( yogaNode_.setHasNewLayout(false); } - if (ReactNativeFeatureFlags:: - enableImageRequestDowngradingForNonVisibleImages()) { - layoutContext.experimental_layoutOrigin = layoutContext.viewportOffset; - layoutContext.experimental_layoutFrame = Rect{ - .origin = layoutContext.viewportOffset, - .size = getLayoutMetrics().frame.size}; - } layout(layoutContext); } @@ -762,21 +755,7 @@ void YogaLayoutableShadowNode::layout(LayoutContext layoutContext) { childNode.setLayoutMetrics(newLayoutMetrics); if (newLayoutMetrics.displayType != DisplayType::None) { - auto childLayoutContext = layoutContext; - if (ReactNativeFeatureFlags:: - enableImageRequestDowngradingForNonVisibleImages()) { - auto childFrame = Rect{ - .origin = layoutContext.experimental_layoutOrigin + - newLayoutMetrics.frame.origin + getContentOriginOffset(false), - .size = newLayoutMetrics.frame.size}; - if (!childNode.getTraits().check( - ShadowNodeTraits::Trait::RootNodeKind)) { - childFrame = childFrame * childNode.getTransform(); - } - childLayoutContext.experimental_layoutOrigin = childFrame.origin; - childLayoutContext.experimental_layoutFrame = childFrame; - } - childNode.layout(childLayoutContext); + childNode.layout(layoutContext); } } } diff --git a/packages/react-native/ReactCommon/react/renderer/core/LayoutContext.h b/packages/react-native/ReactCommon/react/renderer/core/LayoutContext.h index 1fce65c8d972..f54f90159d40 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/LayoutContext.h +++ b/packages/react-native/ReactCommon/react/renderer/core/LayoutContext.h @@ -10,7 +10,6 @@ #include #include -#include namespace facebook::react { @@ -65,18 +64,6 @@ struct LayoutContext { * Viewport size is size of the React Native's root view. */ Size viewportSize{}; - - /* - * Experimental: Origin of the shadow node currently being laid out, in viewport - * coordinates. This is populated while walking the layout tree. - */ - Point experimental_layoutOrigin{}; - - /* - * Experimental: Frame of the shadow node currently being laid out, in viewport - * coordinates after layout transforms are applied. - */ - Rect experimental_layoutFrame{}; }; inline bool operator==(const LayoutContext &lhs, const LayoutContext &rhs) diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageRequestParams.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageRequestParams.h index e1008696d1b2..e960e01b5b5c 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageRequestParams.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageRequestParams.h @@ -61,8 +61,6 @@ class ImageRequestParams { ImageSource loadingIndicatorSource{}; std::string analyticTag{}; Size size{}; - // Consumed by Apple image managers for now; Android keeps Immediate. - ImageRequestPriority priority{ImageRequestPriority::Immediate}; bool operator==(const ImageRequestParams &rhs) const = default; }; diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/cxx/react/renderer/imagemanager/ImageRequestParams.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/cxx/react/renderer/imagemanager/ImageRequestParams.h index 01cf22f44f47..a30f0103dda9 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/cxx/react/renderer/imagemanager/ImageRequestParams.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/cxx/react/renderer/imagemanager/ImageRequestParams.h @@ -8,21 +8,15 @@ #pragma once #include -#include namespace facebook::react { class ImageRequestParams { public: ImageRequestParams() = default; - explicit ImageRequestParams(Float blurRadius, ImageRequestPriority priority = ImageRequestPriority::Immediate) - : blurRadius(blurRadius), priority(priority) - { - } + explicit ImageRequestParams(Float blurRadius) : blurRadius(blurRadius) {} Float blurRadius{}; - // Consumed by Apple image managers for now; other platforms keep Immediate. - ImageRequestPriority priority{ImageRequestPriority::Immediate}; bool operator==(const ImageRequestParams &rhs) const = default; }; diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/ImageManager.mm b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/ImageManager.mm index 3b65868977d6..7e15cdf0a4f2 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/ImageManager.mm +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/ImageManager.mm @@ -37,11 +37,11 @@ ImageRequest ImageManager::requestImage( const ImageSource &imageSource, SurfaceId surfaceId, - const ImageRequestParams &imageRequestParams, + const ImageRequestParams & /*imageRequestParams*/, Tag /*tag*/) const { RCTImageManager *imageManager = (__bridge RCTImageManager *)self_; - return [imageManager requestImage:imageSource surfaceId:surfaceId priority:imageRequestParams.priority]; + return [imageManager requestImage:imageSource surfaceId:surfaceId]; } } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/ImageRequestParams.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/ImageRequestParams.h index e9afe1108018..389f950ed317 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/ImageRequestParams.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/ImageRequestParams.h @@ -8,20 +8,15 @@ #pragma once #include -#include namespace facebook::react { class ImageRequestParams { public: ImageRequestParams() {} - ImageRequestParams(Float blurRadius, ImageRequestPriority priority = ImageRequestPriority::Immediate) - : blurRadius(blurRadius), priority(priority) - { - } + ImageRequestParams(Float blurRadius) : blurRadius(blurRadius) {} Float blurRadius{}; - ImageRequestPriority priority{ImageRequestPriority::Immediate}; bool operator==(const ImageRequestParams &rhs) const = default; }; diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.h index 02e8a2f48e0a..da6223a542d2 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.h @@ -21,8 +21,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithImageLoader:(id)imageLoader; - (facebook::react::ImageRequest)requestImage:(facebook::react::ImageSource)imageSource - surfaceId:(facebook::react::SurfaceId)surfaceId - priority:(facebook::react::ImageRequestPriority)priority; + surfaceId:(facebook::react::SurfaceId)surfaceId; @end diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.mm b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.mm index 40691149f9b0..601dfe45ac38 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.mm +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.mm @@ -36,9 +36,7 @@ - (instancetype)initWithImageLoader:(id)i return self; } -- (ImageRequest)requestImage:(ImageSource)imageSource - surfaceId:(SurfaceId)surfaceId - priority:(ImageRequestPriority)priority +- (ImageRequest)requestImage:(ImageSource)imageSource surfaceId:(SurfaceId)surfaceId { TraceSection s("RCTImageManager::requestImage"); @@ -98,7 +96,7 @@ - (ImageRequest)requestImage:(ImageSource)imageSource scale:imageSource.scale clipped:NO resizeMode:RCTResizeModeStretch - priority:RCTImageLoaderPriorityFromImageRequestPriority(priority) + priority:RCTImageLoaderPriorityImmediate attribution:{ .surfaceId = surfaceId, } diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManagerProtocol.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManagerProtocol.h index 00ff2227cf28..30bfbf391e35 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManagerProtocol.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManagerProtocol.h @@ -12,6 +12,5 @@ @protocol RCTImageManagerProtocol - (facebook::react::ImageRequest)requestImage:(facebook::react::ImageSource)imageSource - surfaceId:(facebook::react::SurfaceId)surfaceId - priority:(facebook::react::ImageRequestPriority)priority; + surfaceId:(facebook::react::SurfaceId)surfaceId; @end diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImagePrimitivesConversions.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImagePrimitivesConversions.h index 1eae15ae4c7a..a13e6fb6d408 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImagePrimitivesConversions.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImagePrimitivesConversions.h @@ -31,19 +31,6 @@ inline static UIViewContentMode RCTContentModeFromImageResizeMode(facebook::reac } } -inline static RCTImageLoaderPriority RCTImageLoaderPriorityFromImageRequestPriority( - facebook::react::ImageRequestPriority imageRequestPriority) -{ - switch (imageRequestPriority) { - case facebook::react::ImageRequestPriority::Immediate: - return RCTImageLoaderPriorityImmediate; - case facebook::react::ImageRequestPriority::Prefetch: - return RCTImageLoaderPriorityPrefetch; - default: - return RCTImageLoaderPriorityImmediate; - } -} - inline std::string toString(const facebook::react::ImageResizeMode &value) { switch (value) { diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTSyncImageManager.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTSyncImageManager.h index 689956e429ab..395f65b9c6b1 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTSyncImageManager.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTSyncImageManager.h @@ -21,8 +21,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithImageLoader:(id)imageLoader; - (facebook::react::ImageRequest)requestImage:(facebook::react::ImageSource)imageSource - surfaceId:(facebook::react::SurfaceId)surfaceId - priority:(facebook::react::ImageRequestPriority)priority; + surfaceId:(facebook::react::SurfaceId)surfaceId; @end diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTSyncImageManager.mm b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTSyncImageManager.mm index 43fbb6a66043..42681164c70b 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTSyncImageManager.mm +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTSyncImageManager.mm @@ -34,9 +34,7 @@ - (instancetype)initWithImageLoader:(id)i return self; } -- (ImageRequest)requestImage:(ImageSource)imageSource - surfaceId:(SurfaceId)surfaceId - priority:(ImageRequestPriority)priority +- (ImageRequest)requestImage:(ImageSource)imageSource surfaceId:(SurfaceId)surfaceId { auto telemetry = std::make_shared(surfaceId); auto sharedCancelationFunction = SharedFunction<>(); @@ -84,7 +82,7 @@ - (ImageRequest)requestImage:(ImageSource)imageSource scale:imageSource.scale clipped:YES resizeMode:RCTResizeModeStretch - priority:RCTImageLoaderPriorityFromImageRequestPriority(priority) + priority:RCTImageLoaderPriorityImmediate attribution:{ .surfaceId = surfaceId, } diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/primitives.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/primitives.h index 2230b11aaef4..66407cdd6fb1 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/primitives.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/primitives.h @@ -169,11 +169,6 @@ enum class ImageResizeMode : int8_t { None = 5, }; -enum class ImageRequestPriority : int8_t { - Immediate = 0, - Prefetch = 1, -}; - class ImageErrorInfo { public: std::string error{}; diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 35b17677b46f..6233fd7a5211 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -337,17 +337,6 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, - enableImageRequestDowngradingForNonVisibleImages: { - defaultValue: false, - metadata: { - dateAdded: '2026-05-21', - description: - 'When enabled, ImageShadowNode downgrades image requests to prefetch priority when layout determines that the image does not intersect the viewport.', - expectedReleaseValue: true, - purpose: 'experimentation', - }, - ossReleaseStage: 'none', - }, enableImmediateUpdateModeForContentOffsetChanges: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index b8b706594ca5..fea6a341e9af 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -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<<1f64eab49a337feb5c9b1b41faf92730>> + * @generated SignedSource<<9665e3af57529f1b50d02c79e7a869eb>> * @flow strict * @noformat */ @@ -76,7 +76,6 @@ export type ReactNativeFeatureFlags = Readonly<{ enableIOSTextBaselineOffsetPerLine: Getter, enableIOSViewClipToPaddingBox: Getter, enableImagePrefetchingAndroid: Getter, - enableImageRequestDowngradingForNonVisibleImages: Getter, enableImmediateUpdateModeForContentOffsetChanges: Getter, enableImperativeFocus: Getter, enableInteropViewManagerClassLookUpOptimizationIOS: Getter, @@ -318,10 +317,6 @@ export const enableIOSViewClipToPaddingBox: Getter = createNativeFlagGe * When enabled, Android will build and initiate image prefetch requests on ImageShadowNode::layout */ export const enableImagePrefetchingAndroid: Getter = createNativeFlagGetter('enableImagePrefetchingAndroid', false); -/** - * When enabled, ImageShadowNode downgrades image requests to prefetch priority when layout determines that the image does not intersect the viewport. - */ -export const enableImageRequestDowngradingForNonVisibleImages: Getter = createNativeFlagGetter('enableImageRequestDowngradingForNonVisibleImages', false); /** * Dispatches state updates for content offset changes synchronously on the main thread. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 263f1ad402d4..1641e8560b8c 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -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<<6bbb0c4532c0762c4ae2dd1d7bc43fb9>> + * @generated SignedSource<<39fb311e84bbff2ff76c8710d493d9d9>> * @flow strict * @noformat */ @@ -52,7 +52,6 @@ export interface Spec extends TurboModule { readonly enableIOSTextBaselineOffsetPerLine?: () => boolean; readonly enableIOSViewClipToPaddingBox?: () => boolean; readonly enableImagePrefetchingAndroid?: () => boolean; - readonly enableImageRequestDowngradingForNonVisibleImages?: () => boolean; readonly enableImmediateUpdateModeForContentOffsetChanges?: () => boolean; readonly enableImperativeFocus?: () => boolean; readonly enableInteropViewManagerClassLookUpOptimizationIOS?: () => boolean; diff --git a/packages/react-native/src/private/testing/fantom/specs/NativeFantom.js b/packages/react-native/src/private/testing/fantom/specs/NativeFantom.js index f5ea5136cff0..a47d97b9aacf 100644 --- a/packages/react-native/src/private/testing/fantom/specs/NativeFantom.js +++ b/packages/react-native/src/private/testing/fantom/specs/NativeFantom.js @@ -129,9 +129,6 @@ interface Spec extends TurboModule { setImageResponse(uri: string, imageResponse: ImageResponse): void; clearImage(uri: string): void; clearAllImages(): void; - getImageRequestCount(uri: string): number; - getImageRequestPriority(uri: string): string; - clearImageRequests(): void; } export default TurboModuleRegistry.getEnforcing( diff --git a/private/react-native-fantom/tester/src/FantomImageManager.h b/private/react-native-fantom/tester/src/FantomImageManager.h deleted file mode 100644 index 46c8d2c02ba2..000000000000 --- a/private/react-native-fantom/tester/src/FantomImageManager.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace facebook::react { - -struct FantomImageRequest { - std::string uri; - ImageRequestPriority priority; -}; - -inline std::string toString(ImageRequestPriority priority) -{ - switch (priority) { - case ImageRequestPriority::Immediate: - return "immediate"; - case ImageRequestPriority::Prefetch: - return "prefetch"; - } -} - -class FantomImageManager final : public ImageManager { - public: - FantomImageManager() : ImageManager(nullptr) {} - - ImageRequest requestImage( - const ImageSource &imageSource, - SurfaceId surfaceId, - const ImageRequestParams &imageRequestParams, - Tag /*tag*/) const override - { - requests_.push_back({imageSource.uri, imageRequestParams.priority}); - return {imageSource, std::make_shared(surfaceId), {}}; - } - - size_t getRequestCount(const std::string &uri) const - { - auto count = size_t{}; - for (const auto &request : requests_) { - if (request.uri == uri) { - ++count; - } - } - return count; - } - - std::string getLatestRequestPriority(const std::string &uri) const - { - for (auto it = requests_.rbegin(); it != requests_.rend(); ++it) { - if (it->uri == uri) { - return toString(it->priority); - } - } - return ""; - } - - void clearRequests() - { - requests_.clear(); - } - - private: - mutable std::vector requests_; -}; - -} // namespace facebook::react diff --git a/private/react-native-fantom/tester/src/NativeFantom.cpp b/private/react-native-fantom/tester/src/NativeFantom.cpp index ff1bcd3725d6..5b18de491450 100644 --- a/private/react-native-fantom/tester/src/NativeFantom.cpp +++ b/private/react-native-fantom/tester/src/NativeFantom.cpp @@ -317,22 +317,4 @@ void NativeFantom::clearAllImages(jsi::Runtime& /*rt*/) { appDelegate_.mountingManager_->imageLoader_->clearAllImages(); } -double NativeFantom::getImageRequestCount( - jsi::Runtime& /*rt*/, - const std::string& uri) { - return static_cast( - appDelegate_.mountingManager_->imageManager_->getRequestCount(uri)); -} - -std::string NativeFantom::getImageRequestPriority( - jsi::Runtime& /*rt*/, - const std::string& uri) { - return appDelegate_.mountingManager_->imageManager_->getLatestRequestPriority( - uri); -} - -void NativeFantom::clearImageRequests(jsi::Runtime& /*rt*/) { - appDelegate_.mountingManager_->imageManager_->clearRequests(); -} - } // namespace facebook::react diff --git a/private/react-native-fantom/tester/src/NativeFantom.h b/private/react-native-fantom/tester/src/NativeFantom.h index 1a69d456dcd7..2c0a19a20fb7 100644 --- a/private/react-native-fantom/tester/src/NativeFantom.h +++ b/private/react-native-fantom/tester/src/NativeFantom.h @@ -140,9 +140,6 @@ class NativeFantom : public NativeFantomCxxSpec { const NativeFantomSetImageResponseImageResponse &imageResponse); void clearImage(jsi::Runtime &rt, const std::string &uri); void clearAllImages(jsi::Runtime &rt); - double getImageRequestCount(jsi::Runtime &rt, const std::string &uri); - std::string getImageRequestPriority(jsi::Runtime &rt, const std::string &uri); - void clearImageRequests(jsi::Runtime &rt); private: TesterAppDelegate &appDelegate_; diff --git a/private/react-native-fantom/tester/src/TesterAppDelegate.cpp b/private/react-native-fantom/tester/src/TesterAppDelegate.cpp index 1ebdaee96470..1fad3777e2f1 100644 --- a/private/react-native-fantom/tester/src/TesterAppDelegate.cpp +++ b/private/react-native-fantom/tester/src/TesterAppDelegate.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -87,7 +86,6 @@ TesterAppDelegate::TesterAppDelegate( DevToolsHttpClientFactoryKey, getHttpClientFactory()); contextContainer->insert( DevToolsWebSocketClientFactoryKey, getWebSocketClientFactory()); - contextContainer->insert(ImageManagerKey, mountingManager_->imageManager_); runLoopObserverManager_ = std::make_shared(); @@ -193,7 +191,6 @@ void TesterAppDelegate::startSurface( LayoutContext layoutContext{ .pointScaleFactor = pointScaleFactor, .viewportOffset = {.x = offsetX, .y = offsetY}, - .viewportSize = extentsDp, }; reactHost_->startSurface( @@ -229,7 +226,6 @@ void TesterAppDelegate::updateSurfaceConstraints( LayoutContext layoutContext{ .pointScaleFactor = pointScaleFactor, - .viewportSize = extentsDp, }; reactHost_->setSurfaceConstraints( diff --git a/private/react-native-fantom/tester/src/TesterMountingManager.cpp b/private/react-native-fantom/tester/src/TesterMountingManager.cpp index 4fd1765bd33e..4526eace7d21 100644 --- a/private/react-native-fantom/tester/src/TesterMountingManager.cpp +++ b/private/react-native-fantom/tester/src/TesterMountingManager.cpp @@ -21,7 +21,6 @@ TesterMountingManager::TesterMountingManager( std::function&& onAfterMount) : onAfterMount_(onAfterMount), renderer_(std::make_unique()) { imageLoader_ = std::make_shared(); - imageManager_ = std::make_shared(); } void TesterMountingManager::executeMount( diff --git a/private/react-native-fantom/tester/src/TesterMountingManager.h b/private/react-native-fantom/tester/src/TesterMountingManager.h index c14a8a7e9334..cdfdf96d584d 100644 --- a/private/react-native-fantom/tester/src/TesterMountingManager.h +++ b/private/react-native-fantom/tester/src/TesterMountingManager.h @@ -8,7 +8,6 @@ #pragma once #include "FantomImageLoader.h" -#include "FantomImageManager.h" #include #include @@ -48,7 +47,6 @@ class TesterMountingManager : public IMountingManager { } std::shared_ptr imageLoader_; - std::shared_ptr imageManager_; std::shared_ptr getImageLoader() noexcept override { diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api index beaf187d8273..347d20311324 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api @@ -2611,7 +2611,6 @@ class facebook::react::ImageRequestParams { public facebook::react::Float blurRadius; public facebook::react::Float fadeDuration; public facebook::react::Float resizeMultiplier; - public facebook::react::ImageRequestPriority priority; public facebook::react::ImageResizeMode resizeMode; public facebook::react::ImageSource defaultSource; public facebook::react::ImageSource loadingIndicatorSource; @@ -6227,11 +6226,6 @@ enum facebook::react::HyphenationFrequency { Normal, } -enum facebook::react::ImageRequestPriority : int8_t { - Immediate, - Prefetch, -} - enum facebook::react::ImageResizeMode : int8_t { Center, Contain, diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api index cd0a69f6db16..c1a244f13f66 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api @@ -2593,7 +2593,6 @@ class facebook::react::ImageRequestParams { public facebook::react::Float blurRadius; public facebook::react::Float fadeDuration; public facebook::react::Float resizeMultiplier; - public facebook::react::ImageRequestPriority priority; public facebook::react::ImageResizeMode resizeMode; public facebook::react::ImageSource defaultSource; public facebook::react::ImageSource loadingIndicatorSource; @@ -6041,11 +6040,6 @@ enum facebook::react::HyphenationFrequency { Normal, } -enum facebook::react::ImageRequestPriority : int8_t { - Immediate, - Prefetch, -} - enum facebook::react::ImageResizeMode : int8_t { Center, Contain, diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api index bdc9fdc54f0f..658f8065fbb0 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api @@ -2608,7 +2608,6 @@ class facebook::react::ImageRequestParams { public facebook::react::Float blurRadius; public facebook::react::Float fadeDuration; public facebook::react::Float resizeMultiplier; - public facebook::react::ImageRequestPriority priority; public facebook::react::ImageResizeMode resizeMode; public facebook::react::ImageSource defaultSource; public facebook::react::ImageSource loadingIndicatorSource; @@ -6218,11 +6217,6 @@ enum facebook::react::HyphenationFrequency { Normal, } -enum facebook::react::ImageRequestPriority : int8_t { - Immediate, - Prefetch, -} - enum facebook::react::ImageResizeMode : int8_t { Center, Contain, diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index 323f80e5161f..9cfe36b68de6 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -1201,7 +1201,7 @@ interface RCTImageLoader : public NSObject { - public virtual facebook::react::ImageRequest requestImage:surfaceId:priority:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId, facebook::react::ImageRequestPriority priority); + public virtual facebook::react::ImageRequest requestImage:surfaceId:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId); public virtual instancetype initWithImageLoader:(id imageLoader); } @@ -1940,7 +1940,7 @@ interface RCTSwitchComponentView : public RCTViewComponentView { } interface RCTSyncImageManager : public NSObject { - public virtual facebook::react::ImageRequest requestImage:surfaceId:priority:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId, facebook::react::ImageRequestPriority priority); + public virtual facebook::react::ImageRequest requestImage:surfaceId:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId); public virtual instancetype initWithImageLoader:(id imageLoader); } @@ -2871,7 +2871,7 @@ protocol RCTImageLoaderWithAttributionProtocol : public RCTImageLoaderProtocol, } protocol RCTImageManagerProtocol : public NSObject { - public virtual facebook::react::ImageRequest requestImage:surfaceId:priority:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId, facebook::react::ImageRequestPriority priority); + public virtual facebook::react::ImageRequest requestImage:surfaceId:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId); } protocol RCTImageRedirectProtocol { @@ -5009,10 +5009,9 @@ class facebook::react::ImageRequest { class facebook::react::ImageRequestParams { public ImageRequestParams(); - public ImageRequestParams(facebook::react::Float blurRadius, facebook::react::ImageRequestPriority priority = facebook::react::ImageRequestPriority::Immediate); + public ImageRequestParams(facebook::react::Float blurRadius); public bool operator==(const facebook::react::ImageRequestParams& rhs) const = default; public facebook::react::Float blurRadius; - public facebook::react::ImageRequestPriority priority; } class facebook::react::ImageResponse { @@ -8370,11 +8369,6 @@ enum facebook::react::HyphenationFrequency { Normal, } -enum facebook::react::ImageRequestPriority : int8_t { - Immediate, - Prefetch, -} - enum facebook::react::ImageResizeMode : int8_t { Center, Contain, diff --git a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api index 0e9f7bf4394e..05cedbce3f5a 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api @@ -1199,7 +1199,7 @@ interface RCTImageLoader : public NSObject { - public virtual facebook::react::ImageRequest requestImage:surfaceId:priority:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId, facebook::react::ImageRequestPriority priority); + public virtual facebook::react::ImageRequest requestImage:surfaceId:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId); public virtual instancetype initWithImageLoader:(id imageLoader); } @@ -1929,7 +1929,7 @@ interface RCTSwitchComponentView : public RCTViewComponentView { } interface RCTSyncImageManager : public NSObject { - public virtual facebook::react::ImageRequest requestImage:surfaceId:priority:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId, facebook::react::ImageRequestPriority priority); + public virtual facebook::react::ImageRequest requestImage:surfaceId:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId); public virtual instancetype initWithImageLoader:(id imageLoader); } @@ -2859,7 +2859,7 @@ protocol RCTImageLoaderWithAttributionProtocol : public RCTImageLoaderProtocol, } protocol RCTImageManagerProtocol : public NSObject { - public virtual facebook::react::ImageRequest requestImage:surfaceId:priority:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId, facebook::react::ImageRequestPriority priority); + public virtual facebook::react::ImageRequest requestImage:surfaceId:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId); } protocol RCTImageRedirectProtocol { @@ -4980,10 +4980,9 @@ class facebook::react::ImageRequest { class facebook::react::ImageRequestParams { public ImageRequestParams(); - public ImageRequestParams(facebook::react::Float blurRadius, facebook::react::ImageRequestPriority priority = facebook::react::ImageRequestPriority::Immediate); + public ImageRequestParams(facebook::react::Float blurRadius); public bool operator==(const facebook::react::ImageRequestParams& rhs) const = default; public facebook::react::Float blurRadius; - public facebook::react::ImageRequestPriority priority; } class facebook::react::ImageResponse { @@ -8212,11 +8211,6 @@ enum facebook::react::HyphenationFrequency { Normal, } -enum facebook::react::ImageRequestPriority : int8_t { - Immediate, - Prefetch, -} - enum facebook::react::ImageResizeMode : int8_t { Center, Contain, diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index 270a0c797f5e..5b98d91d467f 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -1201,7 +1201,7 @@ interface RCTImageLoader : public NSObject { - public virtual facebook::react::ImageRequest requestImage:surfaceId:priority:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId, facebook::react::ImageRequestPriority priority); + public virtual facebook::react::ImageRequest requestImage:surfaceId:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId); public virtual instancetype initWithImageLoader:(id imageLoader); } @@ -1940,7 +1940,7 @@ interface RCTSwitchComponentView : public RCTViewComponentView { } interface RCTSyncImageManager : public NSObject { - public virtual facebook::react::ImageRequest requestImage:surfaceId:priority:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId, facebook::react::ImageRequestPriority priority); + public virtual facebook::react::ImageRequest requestImage:surfaceId:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId); public virtual instancetype initWithImageLoader:(id imageLoader); } @@ -2871,7 +2871,7 @@ protocol RCTImageLoaderWithAttributionProtocol : public RCTImageLoaderProtocol, } protocol RCTImageManagerProtocol : public NSObject { - public virtual facebook::react::ImageRequest requestImage:surfaceId:priority:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId, facebook::react::ImageRequestPriority priority); + public virtual facebook::react::ImageRequest requestImage:surfaceId:(facebook::react::ImageSource imageSource, facebook::react::SurfaceId surfaceId); } protocol RCTImageRedirectProtocol { @@ -5006,10 +5006,9 @@ class facebook::react::ImageRequest { class facebook::react::ImageRequestParams { public ImageRequestParams(); - public ImageRequestParams(facebook::react::Float blurRadius, facebook::react::ImageRequestPriority priority = facebook::react::ImageRequestPriority::Immediate); + public ImageRequestParams(facebook::react::Float blurRadius); public bool operator==(const facebook::react::ImageRequestParams& rhs) const = default; public facebook::react::Float blurRadius; - public facebook::react::ImageRequestPriority priority; } class facebook::react::ImageResponse { @@ -8361,11 +8360,6 @@ enum facebook::react::HyphenationFrequency { Normal, } -enum facebook::react::ImageRequestPriority : int8_t { - Immediate, - Prefetch, -} - enum facebook::react::ImageResizeMode : int8_t { Center, Contain, diff --git a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api index 39c05b7ffbe5..029bdefe3fa0 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api @@ -4589,11 +4589,6 @@ enum facebook::react::HyphenationFrequency { Normal, } -enum facebook::react::ImageRequestPriority : int8_t { - Immediate, - Prefetch, -} - enum facebook::react::ImageResizeMode : int8_t { Center, Contain, diff --git a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api index e0293739574a..bf58f8941d07 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api @@ -4443,11 +4443,6 @@ enum facebook::react::HyphenationFrequency { Normal, } -enum facebook::react::ImageRequestPriority : int8_t { - Immediate, - Prefetch, -} - enum facebook::react::ImageResizeMode : int8_t { Center, Contain, diff --git a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api index 0ccad701dc85..ddeb42c6e2a6 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api @@ -4580,11 +4580,6 @@ enum facebook::react::HyphenationFrequency { Normal, } -enum facebook::react::ImageRequestPriority : int8_t { - Immediate, - Prefetch, -} - enum facebook::react::ImageResizeMode : int8_t { Center, Contain, From bc20ec88ebb901f31d8f554238e97612aa04181b Mon Sep 17 00:00:00 2001 From: Gijs Weterings Date: Wed, 17 Jun 2026 08:04:21 -0700 Subject: [PATCH 017/561] Implement Page.addScriptToEvaluateOnNewDocument CDP handler (#57248) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57248 Implement the CDP `Page.addScriptToEvaluateOnNewDocument` and `Page.removeScriptToEvaluateOnNewDocument` methods in the modern JS inspector (`jsinspector-modern`). `Page.addScriptToEvaluateOnNewDocument` registers a JavaScript snippet that is evaluated in every new JS runtime created for the Host (for example, after a reload), before the application's main bundle runs, matching the standard Chrome DevTools Protocol semantics. This is useful for debugger frontends and tooling that need to install instrumentation ahead of application code. The registered scripts are stored as session state (alongside `Runtime.addBinding` subscriptions in `SessionState`) and replayed onto each new runtime by `RuntimeAgent` via the runtime executor, so they run before any user code and survive reloads. Per CDP semantics the script does not run in the runtime that is current when it is registered; the client triggers `Page.reload` to apply it. `HostAgent` handles both methods, returning the generated script `identifier` from add and removing by `identifier` on remove. Changelog: [General][Added] - Implement the `Page.addScriptToEvaluateOnNewDocument` and `Page.removeScriptToEvaluateOnNewDocument` CDP methods in the modern inspector Reviewed By: hoxyq Differential Revision: D107084044 fbshipit-source-id: 7951028f81f89fbf36418cf8da8a03a7191d228a --- .../jsinspector-modern/HostAgent.cpp | 54 +++++++++++++++++++ .../jsinspector-modern/RuntimeAgent.cpp | 7 +++ .../jsinspector-modern/RuntimeTarget.cpp | 20 +++++++ .../jsinspector-modern/RuntimeTarget.h | 16 ++++++ .../jsinspector-modern/SessionState.h | 31 +++++++++++ .../tests/HostTargetTest.cpp | 53 ++++++++++++++++++ .../api-snapshots/ReactAndroidDebugCxx.api | 8 +++ .../api-snapshots/ReactAndroidNewarchCxx.api | 8 +++ .../api-snapshots/ReactAndroidReleaseCxx.api | 8 +++ .../api-snapshots/ReactAppleDebugCxx.api | 8 +++ .../api-snapshots/ReactAppleNewarchCxx.api | 8 +++ .../api-snapshots/ReactAppleReleaseCxx.api | 8 +++ .../api-snapshots/ReactCommonDebugCxx.api | 8 +++ .../api-snapshots/ReactCommonNewarchCxx.api | 8 +++ .../api-snapshots/ReactCommonReleaseCxx.api | 8 +++ 15 files changed, 253 insertions(+) diff --git a/packages/react-native/ReactCommon/jsinspector-modern/HostAgent.cpp b/packages/react-native/ReactCommon/jsinspector-modern/HostAgent.cpp index 9046456fb985..daef4edc43e2 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/HostAgent.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/HostAgent.cpp @@ -21,8 +21,10 @@ #include #include +#include #include #include +#include #include using namespace std::chrono; @@ -236,6 +238,53 @@ class HostAgent::Impl final { }; } } + if (req.method == "Page.addScriptToEvaluateOnNewDocument") { + // @cdp Page.addScriptToEvaluateOnNewDocument registers a script that + // will be evaluated in every new JS runtime created for this Host + // (e.g. after a reload), BEFORE the app's main bundle runs. We store + // it as session state and let each new RuntimeAgent replay it onto its + // runtime, mirroring the handling of @cdp Runtime.addBinding. Per CDP + // semantics the script does NOT run in the runtime that is current + // when it is registered; the client must reload to apply it. + std::string source = + req.params.isObject() && (req.params.count("source") != 0u) + ? req.params.at("source").asString() + : std::string(); + std::string identifier = + std::to_string(sessionState_.nextScriptToEvaluateOnNewDocumentId++); + sessionState_.scriptsToEvaluateOnNewDocument.push_back( + {.identifier = identifier, .source = std::move(source)}); + + frontendChannel_( + cdp::jsonResult( + req.id, folly::dynamic::object("identifier", identifier))); + + return { + .isFinishedHandlingRequest = true, + .shouldSendOKResponse = false, + }; + } + if (req.method == "Page.removeScriptToEvaluateOnNewDocument") { + std::string identifier = + req.params.isObject() && (req.params.count("identifier") != 0u) + ? req.params.at("identifier").asString() + : std::string(); + auto& scripts = sessionState_.scriptsToEvaluateOnNewDocument; + scripts.erase( + std::remove_if( + scripts.begin(), + scripts.end(), + [&identifier]( + const SessionState::ScriptToEvaluateOnNewDocument& script) { + return script.identifier == identifier; + }), + scripts.end()); + + return { + .isFinishedHandlingRequest = true, + .shouldSendOKResponse = true, + }; + } if (req.method == "Overlay.setPausedInDebuggerMessage") { auto message = req.params.isObject() && (req.params.count("message") != 0u) @@ -397,6 +446,11 @@ class HostAgent::Impl final { return; } + if (requestState.isFinishedHandlingRequest) { + // The handler already sent its own response via frontendChannel_. + return; + } + throw NotImplementedException(req.method); } diff --git a/packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgent.cpp b/packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgent.cpp index 0f3120518ac9..009214586791 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgent.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgent.cpp @@ -33,6 +33,13 @@ RuntimeAgent::RuntimeAgent( } } + // Replay any scripts registered via @cdp + // Page.addScriptToEvaluateOnNewDocument onto this newly created runtime, in + // registration order, so they evaluate before the app's main bundle. + for (const auto& script : sessionState_.scriptsToEvaluateOnNewDocument) { + targetController_.installScriptToEvaluateOnNewDocument(script.source); + } + if (sessionState_.isRuntimeDomainEnabled) { targetController_.notifyDomainStateChanged( RuntimeTargetController::Domain::Runtime, true, *this); diff --git a/packages/react-native/ReactCommon/jsinspector-modern/RuntimeTarget.cpp b/packages/react-native/ReactCommon/jsinspector-modern/RuntimeTarget.cpp index 946983d928de..811d0ea143eb 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/RuntimeTarget.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/RuntimeTarget.cpp @@ -130,6 +130,21 @@ void RuntimeTarget::installBindingHandler(const std::string& bindingName) { }); } +void RuntimeTarget::installScriptToEvaluateOnNewDocument( + const std::string& source) { + jsExecutor_([source](jsi::Runtime& runtime) { + try { + runtime.evaluateJavaScript( + std::make_shared(source), + ""); + } catch (jsi::JSIException&) { + // Swallow exceptions thrown while evaluating the injected script so a + // faulty script cannot break the app. This mirrors how + // installBindingHandler isolates binding-setup failures. + } + }); +} + void RuntimeTarget::installFastRefreshHandler() { jsExecutor_([selfExecutor = executorFromThis()](jsi::Runtime& runtime) { auto globalObj = runtime.global(); @@ -313,6 +328,11 @@ void RuntimeTargetController::installBindingHandler( target_.installBindingHandler(bindingName); } +void RuntimeTargetController::installScriptToEvaluateOnNewDocument( + const std::string& source) { + target_.installScriptToEvaluateOnNewDocument(source); +} + void RuntimeTargetController::enableSamplingProfiler() { target_.enableSamplingProfiler(); } diff --git a/packages/react-native/ReactCommon/jsinspector-modern/RuntimeTarget.h b/packages/react-native/ReactCommon/jsinspector-modern/RuntimeTarget.h index 75eb87410c33..0136ba376eed 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/RuntimeTarget.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/RuntimeTarget.h @@ -129,6 +129,14 @@ class RuntimeTargetController { */ void installBindingHandler(const std::string &bindingName); + /** + * Evaluates the given JavaScript source on the runtime's thread before any + * user code runs. Used to replay @cdp + * Page.addScriptToEvaluateOnNewDocument scripts onto a freshly created + * runtime. + */ + void installScriptToEvaluateOnNewDocument(const std::string &source); + /** * Notifies the target that an agent has received an enable or disable * message for the given domain. @@ -289,6 +297,14 @@ class JSINSPECTOR_EXPORT RuntimeTarget : public EnableExecutorFromThis #include #include +#include namespace facebook::react::jsinspector_modern { @@ -43,6 +44,36 @@ struct SessionState { */ std::unordered_map subscribedBindings; + /** + * A single script registered during this session using @cdp + * Page.addScriptToEvaluateOnNewDocument. + */ + struct ScriptToEvaluateOnNewDocument { + /** Opaque identifier returned to the frontend, used by @cdp + * Page.removeScriptToEvaluateOnNewDocument. */ + std::string identifier; + /** The JavaScript source to evaluate. */ + std::string source; + }; + + /** + * Scripts registered during this session using @cdp + * Page.addScriptToEvaluateOnNewDocument, in registration order. + * + * Like subscribedBindings, these are treated as session state: each new + * RuntimeAgent replays them onto its runtime so they evaluate before any + * user code (i.e. before the app's main bundle). Per CDP semantics they do + * NOT run in the runtime that is current when they are registered - the + * client must trigger a reload (@cdp Page.reload) for them to take effect. + */ + std::vector scriptsToEvaluateOnNewDocument; + + /** + * Monotonic counter for generating the identifiers returned from @cdp + * Page.addScriptToEvaluateOnNewDocument. + */ + unsigned int nextScriptToEvaluateOnNewDocumentId{1}; + /** * Messages logged through the HostAgent::sendConsoleMessage and * InstanceAgent::sendConsoleMessage utilities that have not yet been sent to diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp b/packages/react-native/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp index a4bca34e82b7..e42d4b3cbfec 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp @@ -217,6 +217,59 @@ TEST_F(HostTargetProtocolTest, PageReloadMethod) { })"); } +TEST_F(HostTargetProtocolTest, PageAddAndRemoveScriptToEvaluateOnNewDocument) { + InSequence s; + + // The first registered script gets identifier "1". + EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({ + "id": 1, + "result": {"identifier": "1"} + })"))) + .RetiresOnSaturation(); + toPage_->sendMessage(R"({ + "id": 1, + "method": "Page.addScriptToEvaluateOnNewDocument", + "params": {"source": "globalThis.__a = 1;"} + })"); + + // The second registration gets a distinct, monotonically increasing id "2". + EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({ + "id": 2, + "result": {"identifier": "2"} + })"))) + .RetiresOnSaturation(); + toPage_->sendMessage(R"({ + "id": 2, + "method": "Page.addScriptToEvaluateOnNewDocument", + "params": {"source": "globalThis.__b = 2;"} + })"); + + // Removing a registered script succeeds with an empty result. + EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({ + "id": 3, + "result": {} + })"))) + .RetiresOnSaturation(); + toPage_->sendMessage(R"({ + "id": 3, + "method": "Page.removeScriptToEvaluateOnNewDocument", + "params": {"identifier": "1"} + })"); + + // Removing an unknown identifier is a lenient no-op that still succeeds + // (matching Chrome's behaviour). + EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({ + "id": 4, + "result": {} + })"))) + .RetiresOnSaturation(); + toPage_->sendMessage(R"({ + "id": 4, + "method": "Page.removeScriptToEvaluateOnNewDocument", + "params": {"identifier": "999"} + })"); +} + TEST_F(HostTargetProtocolTest, OverlaySetPausedInDebuggerMessageMethod) { InSequence s; diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api index 347d20311324..c635c5ed20df 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api @@ -10860,6 +10860,7 @@ class facebook::react::jsinspector_modern::RuntimeTargetController { public void emitTracingStateChange(bool isTracing); public void enableSamplingProfiler(); public void installBindingHandler(const std::string& bindingName); + public void installScriptToEvaluateOnNewDocument(const std::string& source); public void notifyDomainStateChanged(facebook::react::jsinspector_modern::RuntimeTargetController::Domain domain, bool enabled, const facebook::react::jsinspector_modern::RuntimeAgent& notifyingAgent); } @@ -11034,7 +11035,14 @@ struct facebook::react::jsinspector_modern::SessionState { public bool isRuntimeDomainEnabled; public facebook::react::jsinspector_modern::RuntimeAgent::ExportedState lastRuntimeAgentExportedState; public std::unordered_map subscribedBindings; + public std::vector scriptsToEvaluateOnNewDocument; public std::vector pendingSimpleConsoleMessages; + public unsigned int nextScriptToEvaluateOnNewDocumentId; +} + +struct facebook::react::jsinspector_modern::SessionState::ScriptToEvaluateOnNewDocument { + public std::string identifier; + public std::string source; } struct facebook::react::jsinspector_modern::SimpleConsoleMessage { diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api index c1a244f13f66..3093c5ef3e1c 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api @@ -10486,6 +10486,7 @@ class facebook::react::jsinspector_modern::RuntimeTargetController { public void emitTracingStateChange(bool isTracing); public void enableSamplingProfiler(); public void installBindingHandler(const std::string& bindingName); + public void installScriptToEvaluateOnNewDocument(const std::string& source); public void notifyDomainStateChanged(facebook::react::jsinspector_modern::RuntimeTargetController::Domain domain, bool enabled, const facebook::react::jsinspector_modern::RuntimeAgent& notifyingAgent); } @@ -10660,7 +10661,14 @@ struct facebook::react::jsinspector_modern::SessionState { public bool isRuntimeDomainEnabled; public facebook::react::jsinspector_modern::RuntimeAgent::ExportedState lastRuntimeAgentExportedState; public std::unordered_map subscribedBindings; + public std::vector scriptsToEvaluateOnNewDocument; public std::vector pendingSimpleConsoleMessages; + public unsigned int nextScriptToEvaluateOnNewDocumentId; +} + +struct facebook::react::jsinspector_modern::SessionState::ScriptToEvaluateOnNewDocument { + public std::string identifier; + public std::string source; } struct facebook::react::jsinspector_modern::SimpleConsoleMessage { diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api index 658f8065fbb0..bb935fb104ac 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api @@ -10713,6 +10713,7 @@ class facebook::react::jsinspector_modern::RuntimeTargetController { public void emitTracingStateChange(bool isTracing); public void enableSamplingProfiler(); public void installBindingHandler(const std::string& bindingName); + public void installScriptToEvaluateOnNewDocument(const std::string& source); public void notifyDomainStateChanged(facebook::react::jsinspector_modern::RuntimeTargetController::Domain domain, bool enabled, const facebook::react::jsinspector_modern::RuntimeAgent& notifyingAgent); } @@ -10887,7 +10888,14 @@ struct facebook::react::jsinspector_modern::SessionState { public bool isRuntimeDomainEnabled; public facebook::react::jsinspector_modern::RuntimeAgent::ExportedState lastRuntimeAgentExportedState; public std::unordered_map subscribedBindings; + public std::vector scriptsToEvaluateOnNewDocument; public std::vector pendingSimpleConsoleMessages; + public unsigned int nextScriptToEvaluateOnNewDocumentId; +} + +struct facebook::react::jsinspector_modern::SessionState::ScriptToEvaluateOnNewDocument { + public std::string identifier; + public std::string source; } struct facebook::react::jsinspector_modern::SimpleConsoleMessage { diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index 9cfe36b68de6..632c83faba04 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -12702,6 +12702,7 @@ class facebook::react::jsinspector_modern::RuntimeTargetController { public void emitTracingStateChange(bool isTracing); public void enableSamplingProfiler(); public void installBindingHandler(const std::string& bindingName); + public void installScriptToEvaluateOnNewDocument(const std::string& source); public void notifyDomainStateChanged(facebook::react::jsinspector_modern::RuntimeTargetController::Domain domain, bool enabled, const facebook::react::jsinspector_modern::RuntimeAgent& notifyingAgent); } @@ -12863,7 +12864,14 @@ struct facebook::react::jsinspector_modern::SessionState { public bool isRuntimeDomainEnabled; public facebook::react::jsinspector_modern::RuntimeAgent::ExportedState lastRuntimeAgentExportedState; public std::unordered_map subscribedBindings; + public std::vector scriptsToEvaluateOnNewDocument; public std::vector pendingSimpleConsoleMessages; + public unsigned int nextScriptToEvaluateOnNewDocumentId; +} + +struct facebook::react::jsinspector_modern::SessionState::ScriptToEvaluateOnNewDocument { + public std::string identifier; + public std::string source; } struct facebook::react::jsinspector_modern::SimpleConsoleMessage { diff --git a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api index 05cedbce3f5a..9a6416e2c1bf 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api @@ -12390,6 +12390,7 @@ class facebook::react::jsinspector_modern::RuntimeTargetController { public void emitTracingStateChange(bool isTracing); public void enableSamplingProfiler(); public void installBindingHandler(const std::string& bindingName); + public void installScriptToEvaluateOnNewDocument(const std::string& source); public void notifyDomainStateChanged(facebook::react::jsinspector_modern::RuntimeTargetController::Domain domain, bool enabled, const facebook::react::jsinspector_modern::RuntimeAgent& notifyingAgent); } @@ -12551,7 +12552,14 @@ struct facebook::react::jsinspector_modern::SessionState { public bool isRuntimeDomainEnabled; public facebook::react::jsinspector_modern::RuntimeAgent::ExportedState lastRuntimeAgentExportedState; public std::unordered_map subscribedBindings; + public std::vector scriptsToEvaluateOnNewDocument; public std::vector pendingSimpleConsoleMessages; + public unsigned int nextScriptToEvaluateOnNewDocumentId; +} + +struct facebook::react::jsinspector_modern::SessionState::ScriptToEvaluateOnNewDocument { + public std::string identifier; + public std::string source; } struct facebook::react::jsinspector_modern::SimpleConsoleMessage { diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index 5b98d91d467f..a7de1287c084 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -12565,6 +12565,7 @@ class facebook::react::jsinspector_modern::RuntimeTargetController { public void emitTracingStateChange(bool isTracing); public void enableSamplingProfiler(); public void installBindingHandler(const std::string& bindingName); + public void installScriptToEvaluateOnNewDocument(const std::string& source); public void notifyDomainStateChanged(facebook::react::jsinspector_modern::RuntimeTargetController::Domain domain, bool enabled, const facebook::react::jsinspector_modern::RuntimeAgent& notifyingAgent); } @@ -12726,7 +12727,14 @@ struct facebook::react::jsinspector_modern::SessionState { public bool isRuntimeDomainEnabled; public facebook::react::jsinspector_modern::RuntimeAgent::ExportedState lastRuntimeAgentExportedState; public std::unordered_map subscribedBindings; + public std::vector scriptsToEvaluateOnNewDocument; public std::vector pendingSimpleConsoleMessages; + public unsigned int nextScriptToEvaluateOnNewDocumentId; +} + +struct facebook::react::jsinspector_modern::SessionState::ScriptToEvaluateOnNewDocument { + public std::string identifier; + public std::string source; } struct facebook::react::jsinspector_modern::SimpleConsoleMessage { diff --git a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api index 029bdefe3fa0..0a98be05bfa5 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api @@ -7864,6 +7864,7 @@ class facebook::react::jsinspector_modern::RuntimeTargetController { public void emitTracingStateChange(bool isTracing); public void enableSamplingProfiler(); public void installBindingHandler(const std::string& bindingName); + public void installScriptToEvaluateOnNewDocument(const std::string& source); public void notifyDomainStateChanged(facebook::react::jsinspector_modern::RuntimeTargetController::Domain domain, bool enabled, const facebook::react::jsinspector_modern::RuntimeAgent& notifyingAgent); } @@ -8025,7 +8026,14 @@ struct facebook::react::jsinspector_modern::SessionState { public bool isRuntimeDomainEnabled; public facebook::react::jsinspector_modern::RuntimeAgent::ExportedState lastRuntimeAgentExportedState; public std::unordered_map subscribedBindings; + public std::vector scriptsToEvaluateOnNewDocument; public std::vector pendingSimpleConsoleMessages; + public unsigned int nextScriptToEvaluateOnNewDocumentId; +} + +struct facebook::react::jsinspector_modern::SessionState::ScriptToEvaluateOnNewDocument { + public std::string identifier; + public std::string source; } struct facebook::react::jsinspector_modern::SimpleConsoleMessage { diff --git a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api index bf58f8941d07..0d05fc986ad8 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api @@ -7692,6 +7692,7 @@ class facebook::react::jsinspector_modern::RuntimeTargetController { public void emitTracingStateChange(bool isTracing); public void enableSamplingProfiler(); public void installBindingHandler(const std::string& bindingName); + public void installScriptToEvaluateOnNewDocument(const std::string& source); public void notifyDomainStateChanged(facebook::react::jsinspector_modern::RuntimeTargetController::Domain domain, bool enabled, const facebook::react::jsinspector_modern::RuntimeAgent& notifyingAgent); } @@ -7853,7 +7854,14 @@ struct facebook::react::jsinspector_modern::SessionState { public bool isRuntimeDomainEnabled; public facebook::react::jsinspector_modern::RuntimeAgent::ExportedState lastRuntimeAgentExportedState; public std::unordered_map subscribedBindings; + public std::vector scriptsToEvaluateOnNewDocument; public std::vector pendingSimpleConsoleMessages; + public unsigned int nextScriptToEvaluateOnNewDocumentId; +} + +struct facebook::react::jsinspector_modern::SessionState::ScriptToEvaluateOnNewDocument { + public std::string identifier; + public std::string source; } struct facebook::react::jsinspector_modern::SimpleConsoleMessage { diff --git a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api index ddeb42c6e2a6..603463858c58 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api @@ -7855,6 +7855,7 @@ class facebook::react::jsinspector_modern::RuntimeTargetController { public void emitTracingStateChange(bool isTracing); public void enableSamplingProfiler(); public void installBindingHandler(const std::string& bindingName); + public void installScriptToEvaluateOnNewDocument(const std::string& source); public void notifyDomainStateChanged(facebook::react::jsinspector_modern::RuntimeTargetController::Domain domain, bool enabled, const facebook::react::jsinspector_modern::RuntimeAgent& notifyingAgent); } @@ -8016,7 +8017,14 @@ struct facebook::react::jsinspector_modern::SessionState { public bool isRuntimeDomainEnabled; public facebook::react::jsinspector_modern::RuntimeAgent::ExportedState lastRuntimeAgentExportedState; public std::unordered_map subscribedBindings; + public std::vector scriptsToEvaluateOnNewDocument; public std::vector pendingSimpleConsoleMessages; + public unsigned int nextScriptToEvaluateOnNewDocumentId; +} + +struct facebook::react::jsinspector_modern::SessionState::ScriptToEvaluateOnNewDocument { + public std::string identifier; + public std::string source; } struct facebook::react::jsinspector_modern::SimpleConsoleMessage { From 08ef7b18d270914c59561873532b5d6d06c4d97b Mon Sep 17 00:00:00 2001 From: Mathieu Acthernoene Date: Wed, 17 Jun 2026 08:31:06 -0700 Subject: [PATCH 018/561] Fix React-RCTAnimatedModuleProvider build failures (#57252) Summary: `React-RCTAnimatedModuleProvider` could fail to build because of two issues in its podspec: - **Missing space between compiler flags**: `new_arch_enabled_flag` and `js_engine_flags()` were concatenated without a separator, producing a single malformed flag (e.g. `-DRCT_NEW_ARCH_ENABLED=1-DUSE_HERMES=1`) instead of two distinct flags. - **Missing Yoga dependency**: the pod uses Yoga headers (through `React-Fabric/animated`) but did not declare the `Yoga` dependency nor its private header search path, leading to a `'yoga/...' file not found` build error. This adds the missing space, declares the `Yoga` dependency, and adds `$(PODS_ROOT)/Headers/Private/Yoga` to the header search paths. ## Changelog: [IOS] [FIXED] - Fix React-RCTAnimatedModuleProvider build by adding the missing Yoga dependency and a missing space between compiler flags Pull Request resolved: https://github.com/react/react-native/pull/57252 Test Plan: Without these changes, building the pod fails with errors such as: ``` fatal error: 'yoga/Yoga.h' file not found ``` and the macro flags being mangled into a single unrecognized define. - Run `pod install` and build the app on iOS. - Confirm `React-RCTAnimatedModuleProvider` compiles and the build succeeds. Reviewed By: zeyap Differential Revision: D108885720 Pulled By: cortinico fbshipit-source-id: b527570857d704b802382334a413ab15879ba13a --- .../React-RCTAnimatedModuleProvider.podspec | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/react-native/ReactApple/RCTAnimatedModuleProvider/React-RCTAnimatedModuleProvider.podspec b/packages/react-native/ReactApple/RCTAnimatedModuleProvider/React-RCTAnimatedModuleProvider.podspec index ac0a79b23e21..c7b786268930 100644 --- a/packages/react-native/ReactApple/RCTAnimatedModuleProvider/React-RCTAnimatedModuleProvider.podspec +++ b/packages/react-native/ReactApple/RCTAnimatedModuleProvider/React-RCTAnimatedModuleProvider.podspec @@ -18,11 +18,12 @@ end is_new_arch_enabled = ENV["RCT_NEW_ARCH_ENABLED"] != "0" new_arch_enabled_flag = (is_new_arch_enabled ? " -DRCT_NEW_ARCH_ENABLED=1" : "") -other_cflags = "$(inherited) " + new_arch_enabled_flag + js_engine_flags() +other_cflags = "$(inherited) " + new_arch_enabled_flag + " " + js_engine_flags() header_search_paths = [ "$(PODS_TARGET_SRCROOT)/../../ReactCommon", "$(PODS_ROOT)/Headers/Private/React-Core", + "$(PODS_ROOT)/Headers/Private/Yoga", "$(PODS_ROOT)/Headers/Public/ReactCommon", ] @@ -52,6 +53,7 @@ Pod::Spec.new do |s| s.dependency "React-Core" s.dependency "React-featureflags" s.dependency "React-Fabric/animated" + s.dependency "Yoga" add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) From 567b9f0aa158193fd2f85a81bcb4f853887cba99 Mon Sep 17 00:00:00 2001 From: Rob Hogan Date: Wed, 17 Jun 2026 09:50:47 -0700 Subject: [PATCH 019/561] Fix OIDC publish, unify top-level package-publishing workflows (#57255) Summary: ## Problem npm Trusted Publishing matches the `workflow_ref` OIDC claim, which is always the top-level workflow filename. npm allows only ONE trusted publisher per package. The prior migration (https://github.com/react/react-native/issues/57099) used `workflow_call` to route all publishes through `publish-npm.yml`, but `workflow_ref` resolves to the *caller* (e.g. `nightly.yml`), not the reusable child, so the Trusted Publisher entry for `publish-npm.yml` never matches. ## Solution Merge all three publish entry points into `publish-npm.yml` itself, triggered by all three event types: - `push.tags: v0.*` -> release mode (was publish-release.yml) - `schedule + workflow_dispatch` -> nightly mode (was nightly.yml) - `push.branches: main, *-stable` -> bumped-packages mode (was publish-bumped-packages.yml) A `determine_mode` job inspects the trigger and sets the mode. Downstream jobs use conditional `if:` expressions to run only the relevant build/publish steps. Since `publish-npm.yml` is now always the top-level workflow, `workflow_ref` always resolves to `publish-npm.yml`, which matches what's already configured on npm. Changelog: [Internal] Pull Request resolved: https://github.com/react/react-native/pull/57255 Reviewed By: cortinico Differential Revision: D108894981 Pulled By: robhogan fbshipit-source-id: 743d5b75cbce1eedfec681ec98fd17332f05f14d --- .github/workflows/nightly.yml | 90 ------ .github/workflows/publish-bumped-packages.yml | 19 -- .github/workflows/publish-npm.yml | 256 +++++++++++++++--- .github/workflows/publish-release.yml | 132 --------- 4 files changed, 214 insertions(+), 283 deletions(-) delete mode 100644 .github/workflows/nightly.yml delete mode 100644 .github/workflows/publish-bumped-packages.yml delete mode 100644 .github/workflows/publish-release.yml diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml deleted file mode 100644 index 1eda5545a47e..000000000000 --- a/.github/workflows/nightly.yml +++ /dev/null @@ -1,90 +0,0 @@ -name: Nightly - -on: - workflow_dispatch: - # nightly build @ 2:15 AM UTC - schedule: - - cron: "15 2 * * *" - -permissions: - contents: read - -jobs: - set_release_type: - runs-on: ubuntu-latest - if: github.repository == 'react/react-native' - outputs: - RELEASE_TYPE: ${{ steps.set_release_type.outputs.RELEASE_TYPE }} - env: - EVENT_NAME: ${{ github.event_name }} - REF: ${{ github.ref }} - steps: - - id: set_release_type - run: | - echo "Setting release type to nightly" - echo "RELEASE_TYPE=nightly" >> $GITHUB_OUTPUT - - prebuild_apple_dependencies: - if: github.repository == 'react/react-native' - uses: ./.github/workflows/prebuild-ios-dependencies.yml - secrets: inherit - - prebuild_react_native_core: - uses: ./.github/workflows/prebuild-ios-core.yml - with: - use-hermes-prebuilt: true - version-type: nightly - secrets: inherit - needs: [prebuild_apple_dependencies] - - build_android: - runs-on: ubuntu-latest - if: github.repository == 'react/react-native' - needs: [set_release_type] - container: - image: reactnativecommunity/react-native-android:latest - env: - TERM: "dumb" - # Set the encoding to resolve a known character encoding issue with decompressing tar.gz files in containers - # via Gradle: https://github.com/gradle/gradle/issues/23391#issuecomment-1878979127 - LC_ALL: C.UTF8 - GRADLE_OPTS: "-Dorg.gradle.daemon=false" - ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} - ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} - ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }} - ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }} - REACT_NATIVE_DOWNLOADS_DIR: /opt/react-native-downloads - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Build Android - uses: ./.github/actions/build-android - with: - release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} - gradle-cache-encryption-key: ${{ secrets.GRADLE_CACHE_ENCRYPTION_KEY }} - - # Delegate the actual npm publish to the shared reusable workflow so - # every `npm publish` in this repo originates from one workflow file — - # required because npm Trusted Publishing only accepts one - # (org, repo, workflow_filename) per package. - build_npm_package: - needs: - [ - set_release_type, - build_android, - prebuild_apple_dependencies, - prebuild_react_native_core, - ] - # The top-level `permissions: contents: read` is the ceiling for - # GITHUB_TOKEN in every job here, including reusable-workflow calls. - # Re-grant `id-token: write` at the job level so publish-npm.yml's - # `publish-react-native` job can mint the OIDC token that npm - # Trusted Publishing exchanges for a publish token. - permissions: - contents: read - id-token: write - uses: ./.github/workflows/publish-npm.yml - secrets: inherit - with: - mode: react-native - release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} diff --git a/.github/workflows/publish-bumped-packages.yml b/.github/workflows/publish-bumped-packages.yml deleted file mode 100644 index 198f1d77749d..000000000000 --- a/.github/workflows/publish-bumped-packages.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Publish Bumped Packages - -on: - push: - branches: - - "main" - - "*-stable" - -jobs: - # Delegate to the shared reusable workflow so every `npm publish` in - # this repo originates from one workflow file — required because npm - # Trusted Publishing only accepts one (org, repo, workflow_filename) - # per package. - publish_bumped_packages: - if: github.repository == 'react/react-native' - uses: ./.github/workflows/publish-npm.yml - secrets: inherit - with: - mode: monorepo-packages diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 62ac1e1db1b1..3b405cd17266 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -1,47 +1,139 @@ -# Reusable workflow that performs every `npm publish` in this repo. +# Single top-level workflow for every npm publish in this repo. # -# Why this exists: npmjs.com Trusted Publishing accepts only ONE -# (org, repo, workflow_filename, environment) tuple per package. If -# `react-native` were published from `publish-release.yml` AND -# `nightly.yml` directly, we'd need two Trusted Publisher entries per -# package — npm rejects that. By moving every `npm publish` into this -# single reusable workflow file, the OIDC `job_workflow_ref` claim -# always resolves to `publish-npm.yml` regardless of which top-level -# workflow triggered the run, so each package needs exactly one -# Trusted Publisher entry pointing here. +# Why: npmjs.com Trusted Publishing matches the `workflow_ref` OIDC claim, +# which is always the TOP-LEVEL workflow filename. npm allows only ONE +# trusted publisher per package, so every `npm publish` must originate +# from the same top-level file. By consolidating all publish triggers +# here, the OIDC claim is always `publish-npm.yml`. # -# See https://docs.npmjs.com/trusted-publishers and -# https://docs.github.com/en/actions/sharing-automations/reusing-workflows . -name: Publish to npm (reusable) +# This replaces the previous separate entry points: +# - publish-release.yml (tag push) → mode=release +# - nightly.yml (cron/dispatch) → mode=nightly +# - publish-bumped-packages.yml (main/stable branch push) → mode=bumped-packages +# +# See https://docs.npmjs.com/trusted-publishers +name: Publish to npm on: - workflow_call: - inputs: - mode: - description: | - 'react-native' runs the full Android/iOS-prebuilt + JS build - and publishes via scripts/releases-ci/publish-npm.js (which - publishes `react-native` and, in nightly mode, every - @react-native/* package). 'monorepo-packages' runs only the - JS build and publishes via - scripts/releases-ci/publish-updated-packages.js (delta-based, - gated on a #publish-packages-to-npm commit message). - type: string - required: true - release-type: - description: "For mode=react-native: release | nightly | dry-run." - type: string - required: false - default: "dry-run" - skip-apple-prebuilts: - description: "For mode=react-native: skip downloading prebuilt Apple artifacts." - type: boolean - required: false - default: false + push: + tags: + - "v0.*.*" # This should match v0.X.Y + - "v0.*.*-rc.*" # This should match v0.X.Y-RC.0 + branches: + - "main" + - "*-stable" + workflow_dispatch: + # nightly build @ 2:15 AM UTC + schedule: + - cron: "15 2 * * *" + +permissions: + contents: read jobs: - publish-react-native: - if: inputs.mode == 'react-native' + # ─── Determine what kind of publish this is ────────────────────── + determine_mode: + runs-on: ubuntu-latest + if: github.repository == 'react/react-native' + outputs: + mode: ${{ steps.mode.outputs.mode }} + release-type: ${{ steps.mode.outputs.release-type }} + steps: + - id: mode + run: | + if [[ "${{ github.ref_type }}" == "tag" ]]; then + echo "mode=release" >> $GITHUB_OUTPUT + echo "release-type=release" >> $GITHUB_OUTPUT + elif [[ "${{ github.event_name }}" == "schedule" || "${{ github.event_name }}" == "workflow_dispatch" ]]; then + echo "mode=nightly" >> $GITHUB_OUTPUT + echo "release-type=nightly" >> $GITHUB_OUTPUT + elif [[ "${{ github.event_name }}" == "push" ]]; then + echo "mode=bumped-packages" >> $GITHUB_OUTPUT + echo "release-type=" >> $GITHUB_OUTPUT + fi + - run: | + echo "Mode: ${{ steps.mode.outputs.mode }}" + echo "Release type: ${{ steps.mode.outputs.release-type }}" + + # ─── Release-only: extract Hermes version for draft release ────── + set_hermes_version: + runs-on: ubuntu-latest + if: github.ref_type == 'tag' + outputs: + HERMES_VERSION: ${{ steps.set_hermes_version.outputs.HERMES_VERSION }} + steps: + - name: Checkout + uses: actions/checkout@v6 + - id: set_hermes_version + run: | + hermes_version=$(grep -oE 'HERMES_VERSION_NAME=([0-9]+\.[0-9]+\.[0-9]+)' packages/react-native/sdks/hermes-engine/version.properties | cut -d'=' -f2) + echo "HERMES_VERSION=$hermes_version" >> $GITHUB_OUTPUT + echo "HERMES_VERSION=$hermes_version" + + # ─── Apple prebuilds (release + nightly) ───────────────────────── + prebuild_apple_dependencies: + needs: [determine_mode] + if: needs.determine_mode.outputs.mode == 'release' || needs.determine_mode.outputs.mode == 'nightly' + uses: ./.github/workflows/prebuild-ios-dependencies.yml + secrets: inherit + + prebuild_react_native_core: + needs: [determine_mode, prebuild_apple_dependencies] + if: needs.determine_mode.outputs.mode == 'release' || needs.determine_mode.outputs.mode == 'nightly' + uses: ./.github/workflows/prebuild-ios-core.yml + secrets: inherit + with: + use-hermes-prebuilt: ${{ needs.determine_mode.outputs.mode == 'nightly' }} + version-type: ${{ needs.determine_mode.outputs.mode == 'nightly' && 'nightly' || '' }} + + # ─── Android build (nightly only — releases handle this in the + # build-npm-package action's Gradle step) ───────────────────── + build_android: + needs: [determine_mode] + if: needs.determine_mode.outputs.mode == 'nightly' + runs-on: ubuntu-latest + container: + image: reactnativecommunity/react-native-android:latest + env: + TERM: "dumb" + # Set the encoding to resolve a known character encoding issue with decompressing tar.gz files in containers + # via Gradle: https://github.com/gradle/gradle/issues/23391#issuecomment-1878979127 + LC_ALL: C.UTF8 + GRADLE_OPTS: "-Dorg.gradle.daemon=false" + ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} + ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} + ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }} + ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }} + REACT_NATIVE_DOWNLOADS_DIR: /opt/react-native-downloads + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Build Android + uses: ./.github/actions/build-android + with: + release-type: nightly + gradle-cache-encryption-key: ${{ secrets.GRADLE_CACHE_ENCRYPTION_KEY }} + + # ─── Build + Publish: react-native + all @react-native/* packages + # (release and nightly modes) ───────────────────────────────── + publish_react_native: + needs: + [ + determine_mode, + build_android, + prebuild_apple_dependencies, + prebuild_react_native_core, + ] + # For nightly, also wait on build_android. Use always() so this + # job isn't skipped when build_android is skipped (release mode). + # The explicit status checks below handle the real gating. + if: | + always() && + (needs.determine_mode.outputs.mode == 'release' || needs.determine_mode.outputs.mode == 'nightly') && + needs.determine_mode.result == 'success' && + needs.prebuild_apple_dependencies.result == 'success' && + needs.prebuild_react_native_core.result == 'success' && + (needs.determine_mode.outputs.mode == 'release' || needs.build_android.result == 'success') runs-on: ubuntu-latest environment: npm-publish # `id-token: write` is required so the npm CLI can mint the OIDC @@ -91,14 +183,17 @@ jobs: - name: Build and Publish NPM Package uses: ./.github/actions/build-npm-package with: - release-type: ${{ inputs.release-type }} + release-type: ${{ needs.determine_mode.outputs.release-type }} gradle-cache-encryption-key: ${{ secrets.GRADLE_CACHE_ENCRYPTION_KEY }} - skip-apple-prebuilts: ${{ inputs.skip-apple-prebuilts && 'true' || 'false' }} - publish-monorepo-packages: - if: inputs.mode == 'monorepo-packages' + # ─── Publish bumped monorepo packages (main/stable push) ───────── + publish_bumped_packages: + needs: [determine_mode] + if: needs.determine_mode.outputs.mode == 'bumped-packages' runs-on: ubuntu-latest environment: npm-publish + # `id-token: write` is required so the npm CLI can mint the OIDC + # token that npm Trusted Publishing exchanges for a publish token. permissions: contents: read id-token: write @@ -134,3 +229,80 @@ jobs: run: yarn build-types --skip-snapshot - name: Find and publish all bumped packages run: node ./scripts/releases-ci/publish-updated-packages.js + + # ─── Release-only: post-publish steps ──────────────────────────── + post_publish: + runs-on: ubuntu-latest + needs: [determine_mode, publish_react_native] + if: needs.determine_mode.outputs.mode == 'release' + env: + REACT_NATIVE_BOT_GITHUB_TOKEN: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + fetch-tags: true + - name: Publish @react-native-community/template + id: publish-template-to-npm + uses: actions/github-script@v8 + with: + github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} + script: | + const {publishTemplate} = require('./.github/workflow-scripts/publishTemplate.js') + const version = "${{ github.ref_name }}" + const isDryRun = false + await publishTemplate(github, version, isDryRun); + - name: Wait for template to be published + timeout-minutes: 3 + uses: actions/github-script@v8 + with: + github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} + script: | + const {verifyPublishedTemplate, isLatest} = require('./.github/workflow-scripts/publishTemplate.js') + const version = "${{ github.ref_name }}" + await verifyPublishedTemplate(version, isLatest()); + - name: Update rn-diff-purge to generate upgrade-support diff + run: | + curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \ + -d "{\"event_type\": \"publish\", \"client_payload\": { \"version\": \"${{ github.ref_name }}\" }}" + - name: Verify Release is on NPM + timeout-minutes: 3 + uses: actions/github-script@v8 + with: + github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} + script: | + const {verifyReleaseOnNpm} = require('./.github/workflow-scripts/verifyReleaseOnNpm.js'); + const {isLatest} = require('./.github/workflow-scripts/publishTemplate.js'); + const version = "${{ github.ref_name }}"; + await verifyReleaseOnNpm(version, isLatest()); + - name: Verify that artifacts are on Maven + uses: actions/github-script@v8 + with: + script: | + const {verifyArtifactsAreOnMaven} = require('./.github/workflow-scripts/verifyArtifactsAreOnMaven.js'); + const version = "${{ github.ref_name }}"; + await verifyArtifactsAreOnMaven(version); + + # ─── Release-only: changelog, podfile bump, draft release ──────── + generate_changelog: + needs: [determine_mode, publish_react_native] + if: needs.determine_mode.outputs.mode == 'release' + uses: ./.github/workflows/generate-changelog.yml + secrets: inherit + + bump_podfile_lock: + needs: [determine_mode, publish_react_native] + if: needs.determine_mode.outputs.mode == 'release' + uses: ./.github/workflows/bump-podfile-lock.yml + secrets: inherit + + create_draft_release: + needs: [determine_mode, generate_changelog, set_hermes_version] + if: needs.determine_mode.outputs.mode == 'release' + uses: ./.github/workflows/create-draft-release.yml + secrets: inherit + with: + hermesVersion: ${{ needs.set_hermes_version.outputs.HERMES_VERSION }} diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml deleted file mode 100644 index b896b89cfd7f..000000000000 --- a/.github/workflows/publish-release.yml +++ /dev/null @@ -1,132 +0,0 @@ -name: Publish Release -on: - push: - tags: - - "v0.*.*" # This should match v0.X.Y - - "v0.*.*-rc.*" # This should match v0.X.Y-RC.0 -jobs: - set_release_type: - runs-on: ubuntu-latest - if: github.repository == 'react/react-native' - outputs: - RELEASE_TYPE: ${{ steps.set_release_type.outputs.RELEASE_TYPE }} - env: - EVENT_NAME: ${{ github.event_name }} - REF: ${{ github.ref }} - steps: - - id: set_release_type - run: | - echo "Setting release type to release" - echo "RELEASE_TYPE=release" >> $GITHUB_OUTPUT - - set_hermes_version: - runs-on: ubuntu-latest - if: github.repository == 'react/react-native' - outputs: - HERMES_VERSION: ${{ steps.set_hermes_version.outputs.HERMES_VERSION }} - steps: - - name: Checkout - uses: actions/checkout@v6 - - id: set_hermes_version - run: | - hermes_version=$(grep -oE 'HERMES_VERSION_NAME=([0-9]+\.[0-9]+\.[0-9]+)' packages/react-native/sdks/hermes-engine/version.properties | cut -d'=' -f2) - echo "HERMES_VERSION=$hermes_version" >> $GITHUB_OUTPUT - echo "HERMES_VERSION=$hermes_version" - - prebuild_apple_dependencies: - if: github.repository == 'react/react-native' - uses: ./.github/workflows/prebuild-ios-dependencies.yml - secrets: inherit - - prebuild_react_native_core: - uses: ./.github/workflows/prebuild-ios-core.yml - secrets: inherit - needs: [prebuild_apple_dependencies] - - # Delegate the actual npm publish to the shared reusable workflow so - # every `npm publish` in this repo originates from one workflow file — - # required because npm Trusted Publishing only accepts one - # (org, repo, workflow_filename) per package. - build_npm_package: - needs: - [ - set_release_type, - prebuild_apple_dependencies, - prebuild_react_native_core, - ] - uses: ./.github/workflows/publish-npm.yml - secrets: inherit - with: - mode: react-native - release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} - - post_publish: - runs-on: ubuntu-latest - needs: [build_npm_package] - env: - REACT_NATIVE_BOT_GITHUB_TOKEN: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} - steps: - - name: Checkout - uses: actions/checkout@v6 - with: - fetch-depth: 0 - fetch-tags: true - - name: Publish @react-native-community/template - id: publish-template-to-npm - uses: actions/github-script@v8 - with: - github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} - script: | - const {publishTemplate} = require('./.github/workflow-scripts/publishTemplate.js') - const version = "${{ github.ref_name }}" - const isDryRun = false - await publishTemplate(github, version, isDryRun); - - name: Wait for template to be published - timeout-minutes: 3 - uses: actions/github-script@v8 - with: - github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} - script: | - const {verifyPublishedTemplate, isLatest} = require('./.github/workflow-scripts/publishTemplate.js') - const version = "${{ github.ref_name }}" - await verifyPublishedTemplate(version, isLatest()); - - name: Update rn-diff-purge to generate upgrade-support diff - run: | - curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \ - -d "{\"event_type\": \"publish\", \"client_payload\": { \"version\": \"${{ github.ref_name }}\" }}" - - name: Verify Release is on NPM - timeout-minutes: 3 - uses: actions/github-script@v8 - with: - github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} - script: | - const {verifyReleaseOnNpm} = require('./.github/workflow-scripts/verifyReleaseOnNpm.js'); - const {isLatest} = require('./.github/workflow-scripts/publishTemplate.js'); - const version = "${{ github.ref_name }}"; - await verifyReleaseOnNpm(version, isLatest()); - - name: Verify that artifacts are on Maven - uses: actions/github-script@v8 - with: - script: | - const {verifyArtifactsAreOnMaven} = require('./.github/workflow-scripts/verifyArtifactsAreOnMaven.js'); - const version = "${{ github.ref_name }}"; - await verifyArtifactsAreOnMaven(version); - - generate_changelog: - needs: build_npm_package - uses: ./.github/workflows/generate-changelog.yml - secrets: inherit - - bump_podfile_lock: - needs: build_npm_package - uses: ./.github/workflows/bump-podfile-lock.yml - secrets: inherit - - create_draft_release: - needs: [generate_changelog, set_hermes_version] - uses: ./.github/workflows/create-draft-release.yml - secrets: inherit - with: - hermesVersion: ${{ needs.set_hermes_version.outputs.HERMES_VERSION }} From 8a3549aa1b6f772df8f6b2d84acc8b4f0ea9613a Mon Sep 17 00:00:00 2001 From: Peter Abbondanzo Date: Wed, 17 Jun 2026 10:25:02 -0700 Subject: [PATCH 020/561] Annotate throwable methods in ColorPropConverter, log bad Android resource lookup (#57239) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57239 Adds logcat logging when resource lookups fail if `resource_paths` is defined for a color prop, and annotates the `ColorProp` calls with the throwable class that they can raise Changelog: [Internal] Reviewed By: zeyap Differential Revision: D108777172 fbshipit-source-id: 1af918b5ad60b303e8c86d9b89b680e73260e0e1 --- .../facebook/react/bridge/ColorPropConverter.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ColorPropConverter.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ColorPropConverter.kt index e4ad53e487b2..b70c2171fc0c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ColorPropConverter.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ColorPropConverter.kt @@ -30,6 +30,7 @@ public object ColorPropConverter { private const val ATTR = "attr" private const val ATTR_SEGMENT = "attr/" + @Throws(JSApplicationCausedNativeException::class) private fun getColorInteger(value: Any?, context: Context): Int? { if (value == null) { return null @@ -64,6 +65,12 @@ public object ColorPropConverter { } } + val attemptedPaths = (0 until resourcePaths.size()).map { resourcePaths.getString(it) } + FLog.w( + ReactConstants.TAG, + "ColorValue: Failed to resolve resource paths: ${attemptedPaths.joinToString(", ")}", + ) + throw JSApplicationCausedNativeException( "ColorValue: None of the paths in the `$JSON_KEY` array resolved to a color resource." ) @@ -73,6 +80,7 @@ public object ColorPropConverter { } @JvmStatic + @Throws(JSApplicationCausedNativeException::class) public fun getColorInstance(value: Any?, context: Context): Color? { if (value == null) { return null @@ -113,6 +121,12 @@ public object ColorPropConverter { } } + val attemptedPaths = (0 until resourcePaths.size()).map { resourcePaths.getString(it) } + FLog.w( + ReactConstants.TAG, + "ColorValue: Failed to resolve resource paths: ${attemptedPaths.joinToString(", ")}", + ) + throw JSApplicationCausedNativeException( "ColorValue: None of the paths in the `$JSON_KEY` array resolved to a color resource." ) @@ -122,6 +136,7 @@ public object ColorPropConverter { } @JvmStatic + @Throws(JSApplicationCausedNativeException::class) public fun getColor(value: Any?, context: Context): Int? { try { if (supportWideGamut()) { @@ -188,6 +203,7 @@ public object ColorPropConverter { return ResourcesCompat.getColor(context.resources, resourceId, context.theme) } + @Throws(Resources.NotFoundException::class) private fun resolveThemeAttribute(context: Context, resourcePath: String): Int { val path = resourcePath.replace(ATTR_SEGMENT, "") val pathTokens = path.split(PACKAGE_DELIMITER) From ef38ba40507aca1c50778a3f94a51c4ee6ea191f Mon Sep 17 00:00:00 2001 From: Christian Falch Date: Wed, 17 Jun 2026 11:19:46 -0700 Subject: [PATCH 021/561] chore(changelog) remove non-merged fix from changelog (#57253) Summary: The changelog wrongly included a change (https://github.com/react/react-native/issues/1216) that wasn't picked due to conflicts. It seems that the Changelog generator included the change even though it was not merged to the release branch. This commit fixes this by removing the fix from 0.83.2 - the fix is available in 0.84. ## Changelog: [GENERAL] [FIXED] - Removed wrong changelog entry in 0.83.2 Pull Request resolved: https://github.com/react/react-native/pull/57253 Reviewed By: fabriziocucci Differential Revision: D108894365 Pulled By: cortinico fbshipit-source-id: 4c5ac5152bc36fd3ea0f766f4f595edb633b33a1 --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54300d67fa39..8ec9dac4f61a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -669,7 +669,6 @@ - **Appearance**: Fix color scheme in appearance state after setting it to unspecified ([08d1764530](https://github.com/facebook/react-native/commit/08d176453095db99300aa77632603ab42c57e152) by [@ismarbesic](https://github.com/ismarbesic)) - **Assets**: Handle `unstable_path` query param in asset URLs ([42986f27a0](https://github.com/facebook/react-native/commit/42986f27a0285e501f71cf5cedacedefdc44c74e) by [@tido64](https://github.com/tido64)) -- **Networking**: Fix incorrect `fetch()` response URL after redirect (https://github.com/facebook/react-native/issues/55248) ([fbe6a686e6](https://github.com/facebook/react-native/commit/fbe6a686e65e70dd61700413084ddc54c0b86765) by [@MarkCSmith](https://github.com/MarkCSmith)) #### Android specific From 9ab5dd857be46ae1d0ba1ef2479bf42b236aee8e Mon Sep 17 00:00:00 2001 From: Sam Zhou Date: Wed, 17 Jun 2026 11:30:47 -0700 Subject: [PATCH 022/561] Deploy 0.319.0 to xplat (#57256) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57256 [changelog](https://github.com/facebook/flow/blob/main/Changelog.md) Changelog: [Internal] Reviewed By: gkz Differential Revision: D108885686 fbshipit-source-id: b31fc3f2987ddb08cbe52daa5e8eef437541c8df --- .flowconfig | 5 ++++- package.json | 4 ++-- scripts/run-ci-javascript-tests.js | 9 +-------- yarn.lock | 8 ++++---- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/.flowconfig b/.flowconfig index aa3784a1c9e2..3a23617f8124 100644 --- a/.flowconfig +++ b/.flowconfig @@ -67,6 +67,9 @@ react.runtime=automatic experimental.deprecated_utilities.excludes=/packages/react-native/Libraries/Renderer/shims/ReactNativeTypes.js experimental.deprecated_utilities.excludes=/packages/react-native/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +experimental.deprecated_colon_extends.excludes=/packages/react-native/Libraries/Renderer/shims/ReactNativeTypes.js +experimental.deprecated_variance_sigils.excludes=/packages/react-native/Libraries/Renderer/shims/ReactNativeTypes.js + ban_spread_key_props=true [lints] @@ -90,4 +93,4 @@ untyped-import untyped-type-import [version] -^0.318.0 +^0.319.0 diff --git a/package.json b/package.json index 274c4e3f32b6..1f25c794fff7 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "clean": "node ./scripts/build/clean.js", "cxx-api-build": "python -m scripts.cxx-api.parser", "cxx-api-validate": "python -m scripts.cxx-api.parser --validate", - "flow-check": "flow check", + "flow-check": "flow full-check", "flow": "flow", "format-check": "prettier --list-different \"./**/*.{js,md,yml,ts,tsx}\"", "format": "npm run prettier && npm run clang-format", @@ -86,7 +86,7 @@ "eslint-plugin-relay": "^1.8.3", "fb-dotslash": "0.5.8", "flow-api-translator": "0.36.1", - "flow-bin": "^0.318.0", + "flow-bin": "^0.319.0", "hermes-eslint": "0.36.1", "hermes-transform": "0.36.1", "ini": "^5.0.0", diff --git a/scripts/run-ci-javascript-tests.js b/scripts/run-ci-javascript-tests.js index 8e62419ba971..7992b46fbcce 100644 --- a/scripts/run-ci-javascript-tests.js +++ b/scripts/run-ci-javascript-tests.js @@ -16,14 +16,12 @@ * --maxWorkers [num] - how many workers, default 1 * --jestBinary [path] - path to jest binary, defaults to local node modules * --yarnBinary [path] - path to yarn binary, defaults to yarn - * --flowBinary [path] - path to flow binary, defaults to running `yarn run flow-check` */ const {execSync} = require('child_process'); const argv /*:Readonly<{ maxWorkers?: number, jestBinary?: string, - flowBinary?: string, yarnBinary?: string, }> */ = // $FlowFixMe[incompatible-type] @@ -34,7 +32,6 @@ const argv /*:Readonly<{ const numberOfMaxWorkers = argv.maxWorkers ?? 1; const JEST_BINARY = argv.jestBinary ?? './node_modules/.bin/jest'; -const FLOW_BINARY = argv.flowBinary; const YARN_BINARY = argv.yarnBinary ?? 'yarn'; class ExecError extends Error { @@ -61,11 +58,7 @@ try { execAndLog(`${YARN_BINARY} run build-types --validate`); describe('Test: Flow check'); - const flowCommand = - FLOW_BINARY == null - ? `${YARN_BINARY} run flow-check` - : `${FLOW_BINARY} full-check`; - execAndLog(flowCommand); + execAndLog(`${YARN_BINARY} run flow-check`); /* * Build @react-native/codegen and @react-native/codegen-typescript-test diff --git a/yarn.lock b/yarn.lock index 1a0833da46ce..21ee2452c58f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4810,10 +4810,10 @@ flow-api-translator@0.36.1: hermes-transform "0.36.1" typescript "5.3.2" -flow-bin@^0.318.0: - version "0.318.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.318.0.tgz#a9fca88958c361255c3939b7a0ab7db6ab4feaf3" - integrity sha512-Q4Z1lrjgBeGNwQEdlD3bJNtjU00bAwgM+HDKQF2kH0gB6ZmEx72kOfYZyL2iok/MIiHqfxU9RhugUqH3ue7YjA== +flow-bin@^0.319.0: + version "0.319.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.319.0.tgz#7ff6c2c531b4d8bd13ec8fecf69e8964f14b6499" + integrity sha512-cl14ZCtILLYmrSW60hoSNfChiA5Og0xacKhqTiSDfSnhJd0P7jLip8IziGE7bOnOi5JIGo+tOlniibkXmckb/w== flow-enums-runtime@^0.0.6: version "0.0.6" From fe53279889ba1e89c99d5b888d36a4294a8abb8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tar=C4=B1k?= Date: Wed, 17 Jun 2026 12:48:06 -0700 Subject: [PATCH 023/561] Avoid sticky header scans for non-sticky VirtualizedLists (#57210) Summary: `VirtualizedList._createRenderMask` always did the sticky-header lookup, even when there were no sticky headers. For a large list scrolled far from the top, that meant walking backward from the first visible item toward index 0 on every render-mask update. This changes that path to: - skip the lookup when `stickyHeaderIndices` is missing or empty - when sticky headers exist, scan the sticky header indices and pick the closest one above the viewport - keep `ListHeaderComponent` offset handling and integer-index behavior ## Changelog: [GENERAL][CHANGED] - Speed up VirtualizedList render-mask creation for large lists by avoiding the old backward sticky-header scan when sticky headers are missing or sparse. ## Affected components This is inside `VirtualizedList`, so the affected callers are: - `VirtualizedList` - `FlatList`, because it renders through `VirtualizedList` - `VirtualizedSectionList` / `SectionList`, because section lists also render through this path `stickyHeaderIndices` does not need to be set to get the no-sticky win. A normal `FlatList` with no sticky headers still used to pay the backward scan. With this change, that case exits before the sticky-header helper runs. When `stickyHeaderIndices` is set, the lookup changes from scanning item indices back toward 0 to scanning only the sticky header index array. The size of the win then depends on how many sticky headers are configured. ## Benchmark Benchmark command: ```sh yarn fantom --benchmarks packages/react-native/Libraries/Lists/__tests__/VirtualizedList-stickyHeaders-benchmark-itest.js --runInBand ``` Fantom Hermes benchmark, 100 samples per case. Values below are median latency for `VirtualizedList._createRenderMask` when the viewport is near the end of the list. Per-call values are under 1 second, so they stay in milliseconds. For 1,000 render-mask updates, values over 1 second are shown in seconds. | Case | One update before | One update after | Speedup | 1,000 updates before | 1,000 updates after | | --- | ---: | ---: | ---: | ---: | ---: | | 100k rows, no sticky headers | 2.664 ms | 0.0034 ms | 780x | 2.66 s | 3.42 ms | | 100k rows, empty sticky headers | 2.632 ms | 0.0033 ms | 800x | 2.63 s | 3.29 ms | | 100k rows, one top sticky header | 2.705 ms | 0.0054 ms | 499x | 2.71 s | 5.42 ms | | 250k rows, no sticky headers | 6.543 ms | 0.0035 ms | 1,892x | 6.54 s | 3.46 ms | | 250k rows, empty sticky headers | 6.579 ms | 0.0033 ms | 2,024x | 6.58 s | 3.25 ms | | 250k rows, one top sticky header | 6.796 ms | 0.0053 ms | 1,294x | 6.80 s | 5.25 ms | | 500k rows, no sticky headers | 13.173 ms | 0.0033 ms | 4,002x | 13.17 s | 3.29 ms | | 500k rows, empty sticky headers | 13.073 ms | 0.0033 ms | 3,997x | 13.07 s | 3.27 ms | | 500k rows, one top sticky header | 13.444 ms | 0.0054 ms | 2,511x | 13.44 s | 5.35 ms | | 750k rows, no sticky headers | 19.524 ms | 0.0033 ms | 6,008x | 19.52 s | 3.25 ms | | 750k rows, empty sticky headers | 19.572 ms | 0.0033 ms | 6,022x | 19.57 s | 3.25 ms | | 750k rows, one top sticky header | 20.304 ms | 0.0054 ms | 3,778x | 20.30 s | 5.37 ms | | 1m rows, no sticky headers | 26.190 ms | 0.0033 ms | 8,058x | 26.19 s | 3.25 ms | | 1m rows, empty sticky headers | 26.039 ms | 0.0033 ms | 8,012x | 26.04 s | 3.25 ms | | 1m rows, one top sticky header | 26.855 ms | 0.0053 ms | 5,075x | 26.86 s | 5.29 ms | This benchmark is intentionally focused on this helper. It does not claim the whole app or whole list render becomes thousands of times faster. It shows that this hot helper is no longer proportional to the scroll distance from the top of the list. Pull Request resolved: https://github.com/react/react-native/pull/57210 Test Plan: ```sh yarn jest packages/virtualized-lists/Lists/__tests__/VirtualizedList-test.js packages/virtualized-lists/Lists/__tests__/VirtualizedSectionList-test.js packages/react-native/Libraries/Lists/__tests__/FlatList-test.js --runInBand ``` Passed: 3 suites, 101 tests, 1 skipped, 76 snapshots. ```sh yarn fantom packages/react-native/Libraries/Lists/__tests__/FlatList-itest.js packages/react-native/Libraries/Lists/__tests__/SectionList-itest.js --runInBand ``` Passed: 2 suites, 64 tests. ```sh yarn flow check ``` Passed: no errors. ```sh ./node_modules/.bin/eslint packages/virtualized-lists/Lists/VirtualizedList.js packages/virtualized-lists/Lists/__tests__/VirtualizedList-test.js packages/react-native/Libraries/Lists/__tests__/VirtualizedList-stickyHeaders-benchmark-itest.js ``` Passed. ```sh git diff --check ``` Passed. Reviewed By: javache Differential Revision: D108890210 Pulled By: Abbondanzo fbshipit-source-id: 7548ba29d77ac14a609665356ab7d09662820abe --- ...lizedList-stickyHeaders-benchmark-itest.js | 85 +++++++++++++++++++ .../Lists/VirtualizedList.js | 40 ++++++--- .../Lists/__tests__/VirtualizedList-test.js | 66 ++++++++++++++ 3 files changed, 178 insertions(+), 13 deletions(-) create mode 100644 packages/react-native/Libraries/Lists/__tests__/VirtualizedList-stickyHeaders-benchmark-itest.js diff --git a/packages/react-native/Libraries/Lists/__tests__/VirtualizedList-stickyHeaders-benchmark-itest.js b/packages/react-native/Libraries/Lists/__tests__/VirtualizedList-stickyHeaders-benchmark-itest.js new file mode 100644 index 000000000000..5e82c49c0bc9 --- /dev/null +++ b/packages/react-native/Libraries/Lists/__tests__/VirtualizedList-stickyHeaders-benchmark-itest.js @@ -0,0 +1,85 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @fantom_mode dev + * @flow strict-local + * @format + */ + +import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; + +import * as Fantom from '@react-native/fantom'; +import VirtualizedList from '@react-native/virtualized-lists/Lists/VirtualizedList'; + +const VIEWPORT_SIZE = 100; +const ROW_COUNTS = [100000, 250000, 500000, 750000, 1000000]; + +type StickyHeaderCase = { + itemCount: number, + name: string, + stickyHeaderIndices?: ReadonlyArray, +}; + +type BenchmarkData = { + length: number, +}; + +const benchmarkCases: Array = []; + +for (let i = 0; i < ROW_COUNTS.length; i++) { + const itemCount = ROW_COUNTS[i]; + const label = itemCount === 1000000 ? '1m' : `${itemCount / 1000}k`; + + benchmarkCases.push( + { + itemCount, + name: `${label} rows without sticky headers`, + }, + { + itemCount, + name: `${label} rows with empty sticky headers`, + stickyHeaderIndices: [], + }, + { + itemCount, + name: `${label} rows with one sticky header at the top`, + stickyHeaderIndices: [0], + }, + ); +} + +function createProps( + itemCount: number, + stickyHeaderIndices?: ReadonlyArray, +) { + return { + data: {length: itemCount}, + getItem: (_data: BenchmarkData, index: number) => index, + getItemCount: (data: BenchmarkData) => data.length, + initialScrollIndex: 1, + stickyHeaderIndices, + }; +} + +Fantom.unstable_benchmark + .suite('VirtualizedList sticky headers', { + disableOptimizedBuildCheck: true, + minIterations: 100, + }) + .test.each( + benchmarkCases, + benchmarkCase => `create render mask for ${benchmarkCase.name}`, + benchmarkCase => { + // $FlowExpectedError[prop-missing] Benchmark exercises an internal helper. + VirtualizedList._createRenderMask( + createProps(benchmarkCase.itemCount, benchmarkCase.stickyHeaderIndices), + { + first: benchmarkCase.itemCount - VIEWPORT_SIZE, + last: benchmarkCase.itemCount - 1, + }, + ); + }, + ); diff --git a/packages/virtualized-lists/Lists/VirtualizedList.js b/packages/virtualized-lists/Lists/VirtualizedList.js index df53cc7ddb78..298331a0b839 100644 --- a/packages/virtualized-lists/Lists/VirtualizedList.js +++ b/packages/virtualized-lists/Lists/VirtualizedList.js @@ -535,16 +535,18 @@ class VirtualizedList extends StateSafePureComponent< renderMask.addCells(initialRegion); } - // The layout coordinates of sticker headers may be off-screen while the + // The layout coordinates of sticky headers may be off-screen while the // actual header is on-screen. Keep the most recent before the viewport // rendered, even if its layout coordinates are not in viewport. - const stickyIndicesSet = new Set(props.stickyHeaderIndices); - VirtualizedList._ensureClosestStickyHeader( - props, - stickyIndicesSet, - renderMask, - cellsAroundViewport.first, - ); + const stickyHeaderIndices = props.stickyHeaderIndices; + if (stickyHeaderIndices != null && stickyHeaderIndices.length > 0) { + VirtualizedList._ensureClosestStickyHeader( + props, + stickyHeaderIndices, + renderMask, + cellsAroundViewport.first, + ); + } } return renderMask; @@ -575,18 +577,30 @@ class VirtualizedList extends StateSafePureComponent< static _ensureClosestStickyHeader( props: VirtualizedListProps, - stickyIndicesSet: Set, + stickyHeaderIndices: ReadonlyArray, renderMask: CellRenderMask, cellIdx: number, ) { const stickyOffset = props.ListHeaderComponent ? 1 : 0; + const targetStickyIndex = cellIdx + stickyOffset; + let closestStickyIndex = null; - for (let itemIdx = cellIdx - 1; itemIdx >= 0; itemIdx--) { - if (stickyIndicesSet.has(itemIdx + stickyOffset)) { - renderMask.addCells({first: itemIdx, last: itemIdx}); - break; + for (let itemIdx = 0; itemIdx < stickyHeaderIndices.length; itemIdx++) { + const stickyIndex = stickyHeaderIndices[itemIdx]; + if ( + Number.isInteger(stickyIndex) && + stickyIndex < targetStickyIndex && + stickyIndex >= stickyOffset && + (closestStickyIndex == null || stickyIndex > closestStickyIndex) + ) { + closestStickyIndex = stickyIndex; } } + + if (closestStickyIndex != null) { + const itemIdx = closestStickyIndex - stickyOffset; + renderMask.addCells({first: itemIdx, last: itemIdx}); + } } _adjustCellsAroundViewport( diff --git a/packages/virtualized-lists/Lists/__tests__/VirtualizedList-test.js b/packages/virtualized-lists/Lists/__tests__/VirtualizedList-test.js index 6fe771ea183a..133b80f9820e 100644 --- a/packages/virtualized-lists/Lists/__tests__/VirtualizedList-test.js +++ b/packages/virtualized-lists/Lists/__tests__/VirtualizedList-test.js @@ -988,6 +988,52 @@ describe('VirtualizedList', () => { // scrolled-past in layout space. expect(component).toMatchSnapshot(); }); + + it('does not add a sticky header to the render mask when no sticky headers are configured', () => { + const expectedRegions = [ + {first: 0, last: 9, isSpacer: true}, + {first: 10, last: 12, isSpacer: false}, + {first: 13, last: 19, isSpacer: true}, + ]; + + expect(createRenderMaskForStickyHeaderTest().enumerateRegions()).toEqual( + expectedRegions, + ); + expect( + createRenderMaskForStickyHeaderTest({ + stickyHeaderIndices: [], + }).enumerateRegions(), + ).toEqual(expectedRegions); + }); + + it('adds the closest sticky header above the viewport from unsorted stickyHeaderIndices', () => { + expect( + createRenderMaskForStickyHeaderTest({ + stickyHeaderIndices: [12, 0, 8.5, 7, 7, -1], + }).enumerateRegions(), + ).toEqual([ + {first: 0, last: 6, isSpacer: true}, + {first: 7, last: 7, isSpacer: false}, + {first: 8, last: 9, isSpacer: true}, + {first: 10, last: 12, isSpacer: false}, + {first: 13, last: 19, isSpacer: true}, + ]); + }); + + it('accounts for ListHeaderComponent offset when adding the closest sticky header', () => { + expect( + createRenderMaskForStickyHeaderTest({ + ListHeaderComponent: () => createElement('Header'), + stickyHeaderIndices: [3], + }).enumerateRegions(), + ).toEqual([ + {first: 0, last: 1, isSpacer: true}, + {first: 2, last: 2, isSpacer: false}, + {first: 3, last: 9, isSpacer: true}, + {first: 10, last: 12, isSpacer: false}, + {first: 13, last: 19, isSpacer: true}, + ]); + }); }); it('unmounts sticky headers moved below viewport', async () => { @@ -2569,6 +2615,26 @@ function fixedHeightItemLayoutProps(height) { }; } +function createRenderMaskForStickyHeaderTest({ + ListHeaderComponent, + stickyHeaderIndices: stickyHeaderIndicesForTest, +} = {}) { + return VirtualizedList._createRenderMask( + { + data: {length: 20}, + getItem: (data, index) => index, + getItemCount: data => data.length, + initialScrollIndex: 1, + ListHeaderComponent, + stickyHeaderIndices: stickyHeaderIndicesForTest, + }, + { + first: 10, + last: 12, + }, + ); +} + let lastViewportLayout; let lastContentLayout; From 9cf30b6e4bcab167e7a3de254ba3ada88ed66374 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Wed, 17 Jun 2026 15:35:01 -0700 Subject: [PATCH 024/561] (Redo D108193641) remove `useNativeDriver` under featureflag animatedForceNativeDriver" (#57250) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57250 ## Changelog: [General] [Added] - remove `useNativeDriver` under featureflag animatedForceNativeDriver When `animatedForceNativeDriver` is enabled, it forces `useNativeDriver` to `true` for all Animated animations and events, overriding the config (explicit `false` set by user will be no-op). Has no effect unless the shared animated backend is enabled, which is required to support native driver for all props. When calling `NativeAnimatedHelper.isNativeDriverForced`, do null check first for backward compatibility in rn-macos Also using this flag to gate the js animation logic that could be cleaned up when this path is fully working. Reviewed By: javache, bmsdave Differential Revision: D108880837 fbshipit-source-id: 2a061ddef3aa49893b88d81caa7f1fdbf28f7842 --- .../Animated/AnimatedImplementation.js | 19 +++++- .../Animated/NativeAnimatedAllowlist.js | 36 +++++++++++ .../__tests__/AnimatedBackend-itest.js | 59 +++++++++++++++++++ .../Animated/animations/Animation.js | 1 + .../Animated/animations/DecayAnimation.js | 1 + .../Animated/animations/SpringAnimation.js | 1 + .../Animated/animations/TimingAnimation.js | 1 + .../ReactNativeFeatureFlags.config.js | 11 ++++ .../private/animated/NativeAnimatedHelper.js | 25 +++++++- .../featureflags/ReactNativeFeatureFlags.js | 8 ++- 10 files changed, 155 insertions(+), 7 deletions(-) diff --git a/packages/react-native/Libraries/Animated/AnimatedImplementation.js b/packages/react-native/Libraries/Animated/AnimatedImplementation.js index 46a08d2e8954..15f1230a47f7 100644 --- a/packages/react-native/Libraries/Animated/AnimatedImplementation.js +++ b/packages/react-native/Libraries/Animated/AnimatedImplementation.js @@ -20,6 +20,7 @@ import type {DecayAnimationConfig} from './animations/DecayAnimation'; import type {SpringAnimationConfig} from './animations/SpringAnimation'; import type {TimingAnimationConfig} from './animations/TimingAnimation'; +import NativeAnimatedHelper from '../../src/private/animated/NativeAnimatedHelper'; import {AnimatedEvent, attachNativeEventImpl} from './AnimatedEvent'; import DecayAnimation from './animations/DecayAnimation'; import SpringAnimation from './animations/SpringAnimation'; @@ -200,7 +201,11 @@ const springImpl = function ( }, _isUsingNativeDriver: function (): boolean { - return config.useNativeDriver || false; + return ( + NativeAnimatedHelper.isNativeDriverForced?.() || + config.useNativeDriver || + false + ); }, } ); @@ -254,7 +259,11 @@ const timingImpl = function ( }, _isUsingNativeDriver: function (): boolean { - return config.useNativeDriver || false; + return ( + NativeAnimatedHelper.isNativeDriverForced?.() || + config.useNativeDriver || + false + ); }, } ); @@ -296,7 +305,11 @@ const decayImpl = function ( }, _isUsingNativeDriver: function (): boolean { - return config.useNativeDriver || false; + return ( + NativeAnimatedHelper.isNativeDriverForced?.() || + config.useNativeDriver || + false + ); }, } ); diff --git a/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js b/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js index c5cecfc828c6..c91017f23fc0 100644 --- a/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js +++ b/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js @@ -78,6 +78,42 @@ const SUPPORTED_STYLES: {[string]: true} = { top: true, /* flex */ flex: true, + flexGrow: true, + flexShrink: true, + flexBasis: true, + aspectRatio: true, + /* margin */ + margin: true, + marginLeft: true, + marginRight: true, + marginTop: true, + marginBottom: true, + marginStart: true, + marginEnd: true, + marginHorizontal: true, + marginVertical: true, + /* padding */ + padding: true, + paddingLeft: true, + paddingRight: true, + paddingTop: true, + paddingBottom: true, + paddingStart: true, + paddingEnd: true, + paddingHorizontal: true, + paddingVertical: true, + /* border width */ + borderWidth: true, + borderLeftWidth: true, + borderRightWidth: true, + borderTopWidth: true, + borderBottomWidth: true, + borderStartWidth: true, + borderEndWidth: true, + /* gap */ + gap: true, + rowGap: true, + columnGap: true, } : {}), }; diff --git a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js index adeaf7e485cf..57b72ea67715 100644 --- a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js +++ b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js @@ -21,6 +21,65 @@ import {Animated, View, useAnimatedValue} from 'react-native'; import {allowStyleProp} from 'react-native/Libraries/Animated/NativeAnimatedAllowlist'; import ReactNativeElement from 'react-native/src/private/webapis/dom/nodes/ReactNativeElement'; +// marginLeft (and the other margin props) are only on the native animated +// allowlist when the shared backend is enabled. This test deliberately does NOT +// call allowStyleProp('marginLeft') — it verifies the prop is supported natively +// out of the box under useSharedAnimatedBackend. +test('animate marginLeft layout prop', () => { + const viewRef = createRef(); + + let _animatedMarginLeft; + let _marginLeftAnimation; + + function MyApp() { + const animatedMarginLeft = useAnimatedValue(0); + _animatedMarginLeft = animatedMarginLeft; + return ( + + ); + } + + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render(); + }); + + Fantom.runTask(() => { + _marginLeftAnimation = Animated.timing(_animatedMarginLeft, { + toValue: 100, + duration: 200, + useNativeDriver: true, + }).start(); + }); + + Fantom.unstable_produceFramesForDuration(100); + + expect(root.getRenderedOutput({props: ['marginLeft']}).toJSX()).toEqual( + , + ); + + Fantom.unstable_produceFramesForDuration(100); + + // TODO: this shouldn't be necessary since animation should be stopped after duration + Fantom.runTask(() => { + _marginLeftAnimation?.stop(); + }); + + expect(root.getRenderedOutput({props: ['marginLeft']}).toJSX()).toEqual( + , + ); +}); + test('animated opacity', () => { let _opacity; let _opacityAnimation; diff --git a/packages/react-native/Libraries/Animated/animations/Animation.js b/packages/react-native/Libraries/Animated/animations/Animation.js index 7322ec03c6b3..83e1a715379a 100644 --- a/packages/react-native/Libraries/Animated/animations/Animation.js +++ b/packages/react-native/Libraries/Animated/animations/Animation.js @@ -70,6 +70,7 @@ export default class Animation { previousAnimation: ?Animation, animatedValue: AnimatedValue, ): void { + // TODO: T274006331 - Remove js-only animation once shared backend is fully rolled out if (!this._useNativeDriver && animatedValue.__isNative === true) { throw new Error( 'Attempting to run JS driven animation on animated node ' + diff --git a/packages/react-native/Libraries/Animated/animations/DecayAnimation.js b/packages/react-native/Libraries/Animated/animations/DecayAnimation.js index 35eb106f5a2b..d6b834b032ee 100644 --- a/packages/react-native/Libraries/Animated/animations/DecayAnimation.js +++ b/packages/react-native/Libraries/Animated/animations/DecayAnimation.js @@ -85,6 +85,7 @@ export default class DecayAnimation extends Animation { this._startTime = Date.now(); const useNativeDriver = this.__startAnimationIfNative(animatedValue); + // TODO: T274006331 - Remove js-only animation once shared backend is fully rolled out if (!useNativeDriver) { this._animationFrame = requestAnimationFrame(() => this.onUpdate()); } diff --git a/packages/react-native/Libraries/Animated/animations/SpringAnimation.js b/packages/react-native/Libraries/Animated/animations/SpringAnimation.js index cb70e4454117..f04a527469b3 100644 --- a/packages/react-native/Libraries/Animated/animations/SpringAnimation.js +++ b/packages/react-native/Libraries/Animated/animations/SpringAnimation.js @@ -225,6 +225,7 @@ export default class SpringAnimation extends Animation { const start = () => { const useNativeDriver = this.__startAnimationIfNative(animatedValue); + // TODO: T274006331 - Remove js-only animation once shared backend is fully rolled out if (!useNativeDriver) { this.onUpdate(); } diff --git a/packages/react-native/Libraries/Animated/animations/TimingAnimation.js b/packages/react-native/Libraries/Animated/animations/TimingAnimation.js index c464334cc376..dffb737a9882 100644 --- a/packages/react-native/Libraries/Animated/animations/TimingAnimation.js +++ b/packages/react-native/Libraries/Animated/animations/TimingAnimation.js @@ -129,6 +129,7 @@ export default class TimingAnimation extends Animation { this._startTime = Date.now(); const useNativeDriver = this.__startAnimationIfNative(animatedValue); + // TODO: T274006331 - Remove js-only animation once shared backend is fully rolled out if (!useNativeDriver) { // Animations that sometimes have 0 duration and sometimes do not // still need to use the native driver when duration is 0 so as to diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 6233fd7a5211..a1f4834ec10e 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -959,6 +959,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + animatedForceNativeDriver: { + defaultValue: false, + metadata: { + dateAdded: '2026-06-10', + description: + 'When enabled, forces `useNativeDriver` to `true` for all Animated animations and events, overriding the config (including an explicit `false`). Has no effect unless the shared animated backend is enabled, which is required to support native driver for all props.', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, animatedShouldDebounceQueueFlush: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/animated/NativeAnimatedHelper.js b/packages/react-native/src/private/animated/NativeAnimatedHelper.js index 9afd64374e5c..74a76280692a 100644 --- a/packages/react-native/src/private/animated/NativeAnimatedHelper.js +++ b/packages/react-native/src/private/animated/NativeAnimatedHelper.js @@ -417,17 +417,35 @@ function assertNativeAnimatedModule(): void { let _warnedMissingNativeAnimated = false; +// Whether the native driver should be forced on for every animation, overriding +// the config (including an explicit `useNativeDriver: false`). This is only safe +// when the shared animated backend is enabled — that backend is what makes every +// prop drivable natively. Forcing native without it would break animations of +// props the legacy native driver doesn't support. +function isNativeDriverForced(): boolean { + return ( + ReactNativeFeatureFlags.animatedForceNativeDriver() && + ReactNativeFeatureFlags.cxxNativeAnimatedEnabled() && + // eslint-disable-next-line + ReactNativeFeatureFlags.useSharedAnimatedBackend() + ); +} + function shouldUseNativeDriver( config: Readonly<{...AnimationConfig, ...}> | EventConfig, ): boolean { - if (config.useNativeDriver == null) { + const forceNativeDriver = isNativeDriverForced(); + + if (config.useNativeDriver == null && !forceNativeDriver) { console.warn( 'Animated: `useNativeDriver` was not specified. This is a required ' + 'option and must be explicitly set to `true` or `false`', ); } - if (config.useNativeDriver === true && !NativeAnimatedModule) { + const useNativeDriver = forceNativeDriver || config.useNativeDriver === true; + + if (useNativeDriver === true && !NativeAnimatedModule) { if (process.env.NODE_ENV !== 'test') { if (!_warnedMissingNativeAnimated) { console.warn( @@ -443,7 +461,7 @@ function shouldUseNativeDriver( return false; } - return config.useNativeDriver || false; + return useNativeDriver; } function transformDataType(value: number | string): number | string { @@ -469,6 +487,7 @@ export default { assertNativeAnimatedModule, generateNewAnimationId, generateNewNodeTag, + isNativeDriverForced, // $FlowExpectedError[unsafe-getters-setters] - unsafe getter lint suppression // $FlowExpectedError[missing-type-arg] - unsafe getter lint suppression get nativeEventEmitter(): NativeEventEmitter { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index fea6a341e9af..71e0b730c834 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -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<<9665e3af57529f1b50d02c79e7a869eb>> + * @generated SignedSource<<68e9dbd18bfcb5e7d5cad27d8663ce66>> * @flow strict * @noformat */ @@ -30,6 +30,7 @@ import { export type ReactNativeFeatureFlagsJsOnly = Readonly<{ jsOnlyTestFlag: Getter, animatedDeferStartOfTimingAnimations: Getter, + animatedForceNativeDriver: Getter, animatedShouldDebounceQueueFlush: Getter, animatedShouldSyncValueBeforeStartCallback: Getter, animatedShouldUseSingleOp: Getter, @@ -145,6 +146,11 @@ export const jsOnlyTestFlag: Getter = createJavaScriptFlagGetter('jsOnl */ export const animatedDeferStartOfTimingAnimations: Getter = createJavaScriptFlagGetter('animatedDeferStartOfTimingAnimations', false); +/** + * When enabled, forces `useNativeDriver` to `true` for all Animated animations and events, overriding the config (including an explicit `false`). Has no effect unless the shared animated backend is enabled, which is required to support native driver for all props. + */ +export const animatedForceNativeDriver: Getter = createJavaScriptFlagGetter('animatedForceNativeDriver', false); + /** * Enables an experimental flush-queue debouncing in Animated.js. */ From faf0951b4e4a5692019aad5d033f2299235e38a0 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Wed, 17 Jun 2026 17:16:18 -0700 Subject: [PATCH 025/561] sync lastest NativeAnimatedHelper to macos (#57257) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57257 ## Changelog: [Internal] [Added] - sync lastest NativeAnimatedHelper to macos Reviewed By: christophpurrer Differential Revision: D108926246 fbshipit-source-id: 60a4c4bfd7470db3fd184d07c4c5e03ceea3c9a1 --- .../Libraries/Animated/AnimatedImplementation.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-native/Libraries/Animated/AnimatedImplementation.js b/packages/react-native/Libraries/Animated/AnimatedImplementation.js index 15f1230a47f7..d14425499cab 100644 --- a/packages/react-native/Libraries/Animated/AnimatedImplementation.js +++ b/packages/react-native/Libraries/Animated/AnimatedImplementation.js @@ -202,7 +202,7 @@ const springImpl = function ( _isUsingNativeDriver: function (): boolean { return ( - NativeAnimatedHelper.isNativeDriverForced?.() || + NativeAnimatedHelper.isNativeDriverForced() || config.useNativeDriver || false ); @@ -260,7 +260,7 @@ const timingImpl = function ( _isUsingNativeDriver: function (): boolean { return ( - NativeAnimatedHelper.isNativeDriverForced?.() || + NativeAnimatedHelper.isNativeDriverForced() || config.useNativeDriver || false ); @@ -306,7 +306,7 @@ const decayImpl = function ( _isUsingNativeDriver: function (): boolean { return ( - NativeAnimatedHelper.isNativeDriverForced?.() || + NativeAnimatedHelper.isNativeDriverForced() || config.useNativeDriver || false ); From 45904c866882f136edde55df2fe453327057d387 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Thu, 18 Jun 2026 00:39:38 -0700 Subject: [PATCH 026/561] Fix Fabric reusing nodes with a stale font scale (#57246) Summary: Fixes https://github.com/react/react-native/issues/52895 The original solution to this issue approached this by comparing the font scale used to lay out respective root nodes and re-cloning measurable nodes in the entire tree when it was different. This didn't work when a node within the tree was cloned from a node with an obsolete font scale stored (with root having the correct one). The new node would use the obsolete value in that pass. This PR changes this approach - instead of comparing font scale in `SurfaceHandler::constraintLayout` (only when it changes), it moves the comparison to happen as part of `configureYogaTree`, similarly to `pointScaleFactor`. This way, nodes with an obsolete value stored get re-cloned using the correct one on each commit instead of only on the first one. ## Changelog: [GENERAL][FIXED] - Fixed Fabric reusing nodes with a stale font scale Pull Request resolved: https://github.com/react/react-native/pull/57246 Test Plan: Issue reproducer ||Before|After| |-|-|-| |Android|