Migrate enableSpannableBuildingUnification to new feature flag system (#42716)

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

Migrates this to the new flag system just added.

Made a quick change to the Android template, to mark Kotlin accessors as `JvmStatic` to make calling from Java more idiomatic.

Next diff will wire to MC.

Changelog: [Internal]

Reviewed By: rubennorte, mdvacca

Differential Revision: D53198874

fbshipit-source-id: 6ab5b279d9ac59733c6e820c25be72383ce0e54a
This commit is contained in:
Nick Gerleman
2024-01-29 18:15:22 -08:00
committed by Facebook GitHub Bot
parent bc6105016c
commit daa308027a
27 changed files with 132 additions and 30 deletions
@@ -1906,7 +1906,6 @@ public class com/facebook/react/config/ReactFeatureFlags {
public static field enableMountHooks Z
public static field enableOnDemandReactChoreographer Z
public static field enableRemoveDeleteTreeInstruction Z
public static field enableSpannableBuildingUnification Z
public static field enableTextSpannableCache Z
public static field enableViewRecycling Z
public static field excludeYogaFromRawProps Z
@@ -152,7 +152,4 @@ public class ReactFeatureFlags {
* when there is work to do.
*/
public static boolean enableOnDemandReactChoreographer = false;
/** Enables the new unified {@link android.text.Spannable} building logic. */
public static boolean enableSpannableBuildingUnification = false;
}
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<52367278b4d0fdf7f436bd8c511d4ffe>>
* @generated SignedSource<<82a7973a820b75c46977931a8b178493>>
*/
/**
@@ -31,23 +31,33 @@ object ReactNativeFeatureFlags {
/**
* Common flag for testing. Do NOT modify.
*/
@JvmStatic
fun commonTestFlag() = accessor.commonTestFlag()
/**
* When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread.
*/
@JvmStatic
fun useModernRuntimeScheduler() = accessor.useModernRuntimeScheduler()
/**
* Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution).
*/
@JvmStatic
fun enableMicrotasks() = accessor.enableMicrotasks()
/**
* When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.
*/
@JvmStatic
fun batchRenderingUpdatesInEventLoop() = accessor.batchRenderingUpdatesInEventLoop()
/**
* Uses new, deduplicated logic for constructing Android Spannables from text fragments
*/
@JvmStatic
fun enableSpannableBuildingUnification() = accessor.enableSpannableBuildingUnification()
/**
* Overrides the feature flags with the ones provided by the given provider
* (generally one that extends `ReactNativeFeatureFlagsDefaults`).
@@ -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<<920bb26d238f935f63a77943df7ef6e2>>
* @generated SignedSource<<881b7f9eb6b1765764b70719155a457c>>
*/
/**
@@ -24,6 +24,7 @@ class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccessor {
private var useModernRuntimeSchedulerCache: Boolean? = null
private var enableMicrotasksCache: Boolean? = null
private var batchRenderingUpdatesInEventLoopCache: Boolean? = null
private var enableSpannableBuildingUnificationCache: Boolean? = null
override fun commonTestFlag(): Boolean {
var cached = commonTestFlagCache
@@ -61,6 +62,15 @@ class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccessor {
return cached
}
override fun enableSpannableBuildingUnification(): Boolean {
var cached = enableSpannableBuildingUnificationCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableSpannableBuildingUnification()
enableSpannableBuildingUnificationCache = cached
}
return cached
}
override fun override(provider: ReactNativeFeatureFlagsProvider) =
ReactNativeFeatureFlagsCxxInterop.override(provider as Any)
@@ -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<<19d0606854e3e34efe67acf9dc1d26b4>>
* @generated SignedSource<<c4908662a6c752ef8dc85f7eb86d1df4>>
*/
/**
@@ -36,6 +36,8 @@ object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic external fun batchRenderingUpdatesInEventLoop(): Boolean
@DoNotStrip @JvmStatic external fun enableSpannableBuildingUnification(): Boolean
@DoNotStrip @JvmStatic external fun override(provider: Any)
@DoNotStrip @JvmStatic external fun dangerouslyReset()
@@ -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<<932fd2768c81d5a5f49929c89d6659ff>>
* @generated SignedSource<<44159bbcf15dc403e40656c71d84516a>>
*/
/**
@@ -30,4 +30,6 @@ open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvider {
override fun enableMicrotasks(): Boolean = false
override fun batchRenderingUpdatesInEventLoop(): Boolean = false
override fun enableSpannableBuildingUnification(): Boolean = false
}
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<6254686d99a8bfd0531ed629655cf673>>
* @generated SignedSource<<85d0ebc43b7c390be7dd89c58f1b7a7a>>
*/
/**
@@ -28,6 +28,7 @@ class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAccessor {
private var useModernRuntimeSchedulerCache: Boolean? = null
private var enableMicrotasksCache: Boolean? = null
private var batchRenderingUpdatesInEventLoopCache: Boolean? = null
private var enableSpannableBuildingUnificationCache: Boolean? = null
override fun commonTestFlag(): Boolean {
var cached = commonTestFlagCache
@@ -69,6 +70,16 @@ class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAccessor {
return cached
}
override fun enableSpannableBuildingUnification(): Boolean {
var cached = enableSpannableBuildingUnificationCache
if (cached == null) {
cached = currentProvider.enableSpannableBuildingUnification()
accessedFeatureFlags.add("enableSpannableBuildingUnification")
enableSpannableBuildingUnificationCache = cached
}
return cached
}
override fun override(provider: ReactNativeFeatureFlagsProvider) {
if (accessedFeatureFlags.isNotEmpty()) {
val accessedFeatureFlagsStr = accessedFeatureFlags.joinToString(separator = ", ") { it }
@@ -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<<c5c87368aae4df966b4b7971aadb79f2>>
* @generated SignedSource<<d5db40f4f25503513c4128892fd12e3f>>
*/
/**
@@ -30,4 +30,6 @@ interface ReactNativeFeatureFlagsProvider {
@DoNotStrip fun enableMicrotasks(): Boolean
@DoNotStrip fun batchRenderingUpdatesInEventLoop(): Boolean
@DoNotStrip fun enableSpannableBuildingUnification(): Boolean
}
@@ -21,7 +21,7 @@ import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
import com.facebook.react.uimanager.IllegalViewOperationException;
import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.NativeViewHierarchyOptimizer;
@@ -93,7 +93,7 @@ public abstract class ReactBaseTextShadowNode extends LayoutShadowNode
boolean supportsInlineViews,
@Nullable Map<Integer, ReactShadowNode> inlineViews,
int start) {
if (ReactFeatureFlags.enableSpannableBuildingUnification) {
if (ReactNativeFeatureFlags.enableSpannableBuildingUnification()) {
buildSpannedFromShadowNodeUnified(
textShadowNode, sb, ops, parentTextAttributes, supportsInlineViews, inlineViews, start);
} else {
@@ -31,7 +31,7 @@ import com.facebook.react.bridge.ReadableNativeMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ReactAccessibilityDelegate.AccessibilityRole;
import com.facebook.react.uimanager.ReactAccessibilityDelegate.Role;
@@ -118,7 +118,7 @@ public class TextLayoutManager {
ReadableArray fragments,
SpannableStringBuilder sb,
List<SetSpanOperation> ops) {
if (ReactFeatureFlags.enableSpannableBuildingUnification) {
if (ReactNativeFeatureFlags.enableSpannableBuildingUnification()) {
buildSpannableFromFragmentsUnified(context, fragments, sb, ops);
} else {
buildSpannableFromFragmentsDuplicated(context, fragments, sb, ops);
@@ -32,7 +32,7 @@ import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.common.mapbuffer.MapBuffer;
import com.facebook.react.common.mapbuffer.ReadableMapBuffer;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ReactAccessibilityDelegate.AccessibilityRole;
import com.facebook.react.uimanager.ReactAccessibilityDelegate.Role;
@@ -140,7 +140,7 @@ public class TextLayoutManagerMapBuffer {
private static void buildSpannableFromFragments(
Context context, MapBuffer fragments, SpannableStringBuilder sb, List<SetSpanOperation> ops) {
if (ReactFeatureFlags.enableSpannableBuildingUnification) {
if (ReactNativeFeatureFlags.enableSpannableBuildingUnification()) {
buildSpannableFromFragmentsUnified(context, fragments, sb, ops);
} else {
buildSpannableFromFragmentsDuplicated(context, fragments, sb, ops);
@@ -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<<bd4482119f1c4963aa4ad1e354f9107d>>
* @generated SignedSource<<36acddfcb6c038dbf523ad669bcedeba>>
*/
/**
@@ -43,6 +43,11 @@ bool JReactNativeFeatureFlagsCxxInterop::batchRenderingUpdatesInEventLoop(
return ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop();
}
bool JReactNativeFeatureFlagsCxxInterop::enableSpannableBuildingUnification(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableSpannableBuildingUnification();
}
void JReactNativeFeatureFlagsCxxInterop::override(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/,
jni::alias_ref<jobject> provider) {
@@ -72,6 +77,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"batchRenderingUpdatesInEventLoop",
JReactNativeFeatureFlagsCxxInterop::batchRenderingUpdatesInEventLoop),
makeNativeMethod(
"enableSpannableBuildingUnification",
JReactNativeFeatureFlagsCxxInterop::enableSpannableBuildingUnification),
});
}
@@ -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<<b7304c29a002ce5a8a612d7a08d798ff>>
* @generated SignedSource<<b903dab48f817589883d7f41cc5674f0>>
*/
/**
@@ -42,6 +42,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool batchRenderingUpdatesInEventLoop(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableSpannableBuildingUnification(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static void override(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>,
jni::alias_ref<jobject> provider);
@@ -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<<91f988022fbff7eba632f2ba46056025>>
* @generated SignedSource<<5f99c47d357e45524b359e6517d1f2eb>>
*/
/**
@@ -51,4 +51,10 @@ bool ReactNativeFeatureFlagsProviderHolder::batchRenderingUpdatesInEventLoop() {
return method(javaProvider_);
}
bool ReactNativeFeatureFlagsProviderHolder::enableSpannableBuildingUnification() {
static const auto method =
getJClass()->getMethod<jboolean()>("enableSpannableBuildingUnification");
return method(javaProvider_);
}
} // namespace facebook::react
@@ -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<<3550f7ee28a53a4024a48301ee38ce7e>>
* @generated SignedSource<<6aaa06ae0c12de2f432374d0cd048460>>
*/
/**
@@ -39,6 +39,7 @@ class ReactNativeFeatureFlagsProviderHolder
bool useModernRuntimeScheduler() override;
bool enableMicrotasks() override;
bool batchRenderingUpdatesInEventLoop() override;
bool enableSpannableBuildingUnification() override;
private:
jni::global_ref<jobject> javaProvider_;
@@ -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<<eb9bb346a84321197849de2dd8bf7dc3>>
* @generated SignedSource<<809c23db6d36e18d448554900e462aa0>>
*/
/**
@@ -37,6 +37,10 @@ bool ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop() {
return getAccessor().batchRenderingUpdatesInEventLoop();
}
bool ReactNativeFeatureFlags::enableSpannableBuildingUnification() {
return getAccessor().enableSpannableBuildingUnification();
}
void ReactNativeFeatureFlags::override(
std::unique_ptr<ReactNativeFeatureFlagsProvider> provider) {
getAccessor().override(std::move(provider));
@@ -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<<be203871f94ca134f75b803b7d79a5ab>>
* @generated SignedSource<<ea6c88fb2c3fcaa35b5886b8f8ceb769>>
*/
/**
@@ -52,6 +52,11 @@ class ReactNativeFeatureFlags {
*/
static bool batchRenderingUpdatesInEventLoop();
/**
* Uses new, deduplicated logic for constructing Android Spannables from text fragments
*/
static bool enableSpannableBuildingUnification();
/**
* Overrides the feature flags with the ones provided by the given provider
* (generally one that extends `ReactNativeFeatureFlagsDefaults`).
@@ -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<<5df50987338c0541436b11cd5433013c>>
* @generated SignedSource<<15858c6ab96e90350aa5f29eb108b051>>
*/
/**
@@ -96,6 +96,23 @@ bool ReactNativeFeatureFlagsAccessor::batchRenderingUpdatesInEventLoop() {
return batchRenderingUpdatesInEventLoop_.value();
}
bool ReactNativeFeatureFlagsAccessor::enableSpannableBuildingUnification() {
if (!enableSpannableBuildingUnification_.has_value()) {
// Mark the flag as accessed.
static const char* flagName = "enableSpannableBuildingUnification";
if (std::find(
accessedFeatureFlags_.begin(),
accessedFeatureFlags_.end(),
flagName) == accessedFeatureFlags_.end()) {
accessedFeatureFlags_.push_back(flagName);
}
enableSpannableBuildingUnification_.emplace(currentProvider_->enableSpannableBuildingUnification());
}
return enableSpannableBuildingUnification_.value();
}
void ReactNativeFeatureFlagsAccessor::override(
std::unique_ptr<ReactNativeFeatureFlagsProvider> provider) {
if (!accessedFeatureFlags_.empty()) {
@@ -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<<11335a9c0d793a3a5a0dfdb01cd43efd>>
* @generated SignedSource<<938f1f3ad6aa3343beb3ad7707a49a87>>
*/
/**
@@ -34,6 +34,7 @@ class ReactNativeFeatureFlagsAccessor {
bool useModernRuntimeScheduler();
bool enableMicrotasks();
bool batchRenderingUpdatesInEventLoop();
bool enableSpannableBuildingUnification();
void override(std::unique_ptr<ReactNativeFeatureFlagsProvider> provider);
@@ -45,6 +46,7 @@ class ReactNativeFeatureFlagsAccessor {
std::optional<bool> useModernRuntimeScheduler_;
std::optional<bool> enableMicrotasks_;
std::optional<bool> batchRenderingUpdatesInEventLoop_;
std::optional<bool> enableSpannableBuildingUnification_;
};
} // namespace facebook::react
@@ -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<<b354cb54b822e2dfa3e093d39fb4da4e>>
* @generated SignedSource<<18dc9a1aa23d156bc94e426ee1864359>>
*/
/**
@@ -42,6 +42,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
bool batchRenderingUpdatesInEventLoop() override {
return false;
}
bool enableSpannableBuildingUnification() override {
return false;
}
};
} // namespace facebook::react
@@ -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<<6bf1fc0d7b32a36041c2371fe191792b>>
* @generated SignedSource<<2828ad8eb7ea0a0ea9cb0240eadedeb8>>
*/
/**
@@ -29,6 +29,7 @@ class ReactNativeFeatureFlagsProvider {
virtual bool useModernRuntimeScheduler() = 0;
virtual bool enableMicrotasks() = 0;
virtual bool batchRenderingUpdatesInEventLoop() = 0;
virtual bool enableSpannableBuildingUnification() = 0;
};
} // namespace facebook::react
@@ -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<<01b940f6716765f9359c42180db497c0>>
* @generated SignedSource<<de38e5abc0430aedc0fe94f0c73fee3d>>
*/
/**
@@ -55,4 +55,9 @@ bool NativeReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop(
return ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop();
}
bool NativeReactNativeFeatureFlags::enableSpannableBuildingUnification(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableSpannableBuildingUnification();
}
} // namespace facebook::react
@@ -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<<200fe2cf84a044164c60f6dd3c5569dd>>
* @generated SignedSource<<b6444bb426632dfb672312df3384127f>>
*/
/**
@@ -37,6 +37,8 @@ class NativeReactNativeFeatureFlags
bool enableMicrotasks(jsi::Runtime& runtime);
bool batchRenderingUpdatesInEventLoop(jsi::Runtime& runtime);
bool enableSpannableBuildingUnification(jsi::Runtime& runtime);
};
} // namespace facebook::react
@@ -15,6 +15,10 @@
"batchRenderingUpdatesInEventLoop": {
"description": "When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.",
"defaultValue": false
},
"enableSpannableBuildingUnification": {
"description": "Uses new, deduplicated logic for constructing Android Spannables from text fragments",
"defaultValue": false
}
},
"jsOnly": {
@@ -41,6 +41,7 @@ ${Object.entries(config.common)
` /**
* ${flagConfig.description}
*/
@JvmStatic
fun ${flagName}() = accessor.${flagName}()`,
)
.join('\n\n')}
@@ -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<<564159837241d197ebc3084ff9e72b7c>>
* @generated SignedSource<<80726297990981a85ae106f8566ec662>>
* @flow strict-local
*/
@@ -27,6 +27,7 @@ export interface Spec extends TurboModule {
+useModernRuntimeScheduler?: () => boolean;
+enableMicrotasks?: () => boolean;
+batchRenderingUpdatesInEventLoop?: () => boolean;
+enableSpannableBuildingUnification?: () => boolean;
}
const NativeReactNativeFeatureFlags: ?Spec = TurboModuleRegistry.get<Spec>(
@@ -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<<4e4ce58c1ce1a95355bba0dfe099e26e>>
* @generated SignedSource<<fbc0fd8f6eb3577e80254d855b2cd026>>
* @flow strict-local
*/
@@ -37,6 +37,7 @@ export type ReactNativeFeatureFlags = {
useModernRuntimeScheduler: Getter<boolean>,
enableMicrotasks: Getter<boolean>,
batchRenderingUpdatesInEventLoop: Getter<boolean>,
enableSpannableBuildingUnification: Getter<boolean>,
}
/**
@@ -60,6 +61,10 @@ export const enableMicrotasks: Getter<boolean> = createNativeFlagGetter('enableM
* When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.
*/
export const batchRenderingUpdatesInEventLoop: Getter<boolean> = createNativeFlagGetter('batchRenderingUpdatesInEventLoop', false);
/**
* Uses new, deduplicated logic for constructing Android Spannables from text fragments
*/
export const enableSpannableBuildingUnification: Getter<boolean> = createNativeFlagGetter('enableSpannableBuildingUnification', false);
/**
* Overrides the feature flags with the provided methods.