Skip to content

Commit 441f5c7

Browse files
committed
Introduce fuseboxFrameRecordingEnabled flag, gate existing code (react#55941)
Summary: Pull Request resolved: react#55941 Replaces the previous `globalThis.enableTimelineFrames` setup with backend gating. Enables us to: - Iterate more safely by gating Android/iOS/C++ code - Have a per-app rollout at Meta Changelog: [Internal] Reviewed By: vzaidman Differential Revision: D95405444 fbshipit-source-id: 0c41f10059b28ed940a12a44707946baa310bdfb
1 parent 1767dfc commit 441f5c7

32 files changed

Lines changed: 208 additions & 42 deletions

.claude/settings.local.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
{
22
"permissions": {
33
"allow": [
4-
"Bash(gh log-list:*)"
4+
"Bash(gh log-list:*)",
5+
"Bash(for f:*)",
6+
"Bash(do)",
7+
"Bash(echo \"=== $f ===\")",
8+
"Read(//Users/huntie/Development/forks/facebook/react-native/**)",
9+
"Bash(done)"
510
]
611
}
712
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/InspectorFlags.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ internal object InspectorFlags {
2020
@DoNotStrip @JvmStatic external fun getFuseboxEnabled(): Boolean
2121

2222
@DoNotStrip @JvmStatic external fun getIsProfilingBuild(): Boolean
23+
24+
@DoNotStrip @JvmStatic external fun getFrameRecordingEnabled(): Boolean
2325
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,12 @@ public object ReactNativeFeatureFlags {
372372
@JvmStatic
373373
public fun fuseboxEnabledRelease(): Boolean = accessor.fuseboxEnabledRelease()
374374

375+
/**
376+
* Enable frame timings and screenshots support in the React Native DevTools CDP backend. This flag is global and should not be changed across React Host lifetimes.
377+
*/
378+
@JvmStatic
379+
public fun fuseboxFrameRecordingEnabled(): Boolean = accessor.fuseboxFrameRecordingEnabled()
380+
375381
/**
376382
* Enable network inspection support in the React Native DevTools CDP backend. Requires `enableBridgelessArchitecture`. This flag is global and should not be changed across React Host lifetimes.
377383
*/

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
7777
private var fixMappingOfEventPrioritiesBetweenFabricAndReactCache: Boolean? = null
7878
private var fuseboxAssertSingleHostStateCache: Boolean? = null
7979
private var fuseboxEnabledReleaseCache: Boolean? = null
80+
private var fuseboxFrameRecordingEnabledCache: Boolean? = null
8081
private var fuseboxNetworkInspectionEnabledCache: Boolean? = null
8182
private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null
8283
private var overrideBySynchronousMountPropsAtMountingAndroidCache: Boolean? = null
@@ -619,6 +620,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
619620
return cached
620621
}
621622

623+
override fun fuseboxFrameRecordingEnabled(): Boolean {
624+
var cached = fuseboxFrameRecordingEnabledCache
625+
if (cached == null) {
626+
cached = ReactNativeFeatureFlagsCxxInterop.fuseboxFrameRecordingEnabled()
627+
fuseboxFrameRecordingEnabledCache = cached
628+
}
629+
return cached
630+
}
631+
622632
override fun fuseboxNetworkInspectionEnabled(): Boolean {
623633
var cached = fuseboxNetworkInspectionEnabledCache
624634
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
142142

143143
@DoNotStrip @JvmStatic public external fun fuseboxEnabledRelease(): Boolean
144144

145+
@DoNotStrip @JvmStatic public external fun fuseboxFrameRecordingEnabled(): Boolean
146+
145147
@DoNotStrip @JvmStatic public external fun fuseboxNetworkInspectionEnabled(): Boolean
146148

147149
@DoNotStrip @JvmStatic public external fun hideOffscreenVirtualViewsOnIOS(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
137137

138138
override fun fuseboxEnabledRelease(): Boolean = false
139139

140+
override fun fuseboxFrameRecordingEnabled(): Boolean = false
141+
140142
override fun fuseboxNetworkInspectionEnabled(): Boolean = true
141143

142144
override fun hideOffscreenVirtualViewsOnIOS(): Boolean = false

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
8181
private var fixMappingOfEventPrioritiesBetweenFabricAndReactCache: Boolean? = null
8282
private var fuseboxAssertSingleHostStateCache: Boolean? = null
8383
private var fuseboxEnabledReleaseCache: Boolean? = null
84+
private var fuseboxFrameRecordingEnabledCache: Boolean? = null
8485
private var fuseboxNetworkInspectionEnabledCache: Boolean? = null
8586
private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null
8687
private var overrideBySynchronousMountPropsAtMountingAndroidCache: Boolean? = null
@@ -680,6 +681,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
680681
return cached
681682
}
682683

684+
override fun fuseboxFrameRecordingEnabled(): Boolean {
685+
var cached = fuseboxFrameRecordingEnabledCache
686+
if (cached == null) {
687+
cached = currentProvider.fuseboxFrameRecordingEnabled()
688+
accessedFeatureFlags.add("fuseboxFrameRecordingEnabled")
689+
fuseboxFrameRecordingEnabledCache = cached
690+
}
691+
return cached
692+
}
693+
683694
override fun fuseboxNetworkInspectionEnabled(): Boolean {
684695
var cached = fuseboxNetworkInspectionEnabledCache
685696
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ public interface ReactNativeFeatureFlagsProvider {
137137

138138
@DoNotStrip public fun fuseboxEnabledRelease(): Boolean
139139

140+
@DoNotStrip public fun fuseboxFrameRecordingEnabled(): Boolean
141+
140142
@DoNotStrip public fun fuseboxNetworkInspectionEnabled(): Boolean
141143

142144
@DoNotStrip public fun hideOffscreenVirtualViewsOnIOS(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,16 +1573,18 @@ public class ReactHostImpl(
15731573
when (state) {
15741574
TracingState.ENABLED_IN_BACKGROUND_MODE,
15751575
TracingState.ENABLED_IN_CDP_MODE -> {
1576-
val observer =
1577-
FrameTimingsObserver(
1578-
_screenshotsEnabled,
1579-
{ frameTimingsSequence ->
1580-
inspectorTarget.recordFrameTimings(frameTimingsSequence)
1581-
},
1582-
)
1583-
observer.setCurrentWindow(currentActivity?.window)
1584-
observer.start()
1585-
frameTimingsObserver = observer
1576+
if (InspectorFlags.getFrameRecordingEnabled()) {
1577+
val observer =
1578+
FrameTimingsObserver(
1579+
_screenshotsEnabled,
1580+
{ frameTimingsSequence ->
1581+
inspectorTarget.recordFrameTimings(frameTimingsSequence)
1582+
},
1583+
)
1584+
observer.setCurrentWindow(currentActivity?.window)
1585+
observer.start()
1586+
frameTimingsObserver = observer
1587+
}
15861588
}
15871589
TracingState.DISABLED -> {
15881590
frameTimingsObserver?.stop()

packages/react-native/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ bool JInspectorFlags::getIsProfilingBuild(jni::alias_ref<jclass> /*unused*/) {
2121
return inspectorFlags.getIsProfilingBuild();
2222
}
2323

24+
bool JInspectorFlags::getFrameRecordingEnabled(
25+
jni::alias_ref<jclass> /*unused*/) {
26+
auto& inspectorFlags = InspectorFlags::getInstance();
27+
return inspectorFlags.getFrameRecordingEnabled();
28+
}
29+
2430
void JInspectorFlags::registerNatives() {
2531
javaClassLocal()->registerNatives({
2632
makeNativeMethod("getFuseboxEnabled", JInspectorFlags::getFuseboxEnabled),
@@ -29,6 +35,11 @@ void JInspectorFlags::registerNatives() {
2935
makeNativeMethod(
3036
"getIsProfilingBuild", JInspectorFlags::getIsProfilingBuild),
3137
});
38+
javaClassLocal()->registerNatives({
39+
makeNativeMethod(
40+
"getFrameRecordingEnabled",
41+
JInspectorFlags::getFrameRecordingEnabled),
42+
});
3243
}
3344

3445
} // namespace facebook::react::jsinspector_modern

0 commit comments

Comments
 (0)