react-native 0.83.4 → 0.83.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +1 -1
  2. package/Libraries/Utilities/Appearance.js +6 -1
  3. package/React/Base/RCTVersion.m +1 -1
  4. package/React/DevSupport/RCTFrameTimingsObserver.h +24 -0
  5. package/React/DevSupport/RCTFrameTimingsObserver.mm +298 -0
  6. package/React/FBReactNativeSpec/FBReactNativeSpecJSI.h +16 -0
  7. package/ReactAndroid/api/ReactAndroid.api +0 -9
  8. package/ReactAndroid/gradle.properties +1 -1
  9. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgelessDevSupportManager.kt +2 -2
  10. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.kt +7 -7
  11. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/InspectorFlags.kt +4 -0
  12. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingSequence.kt +16 -0
  13. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingsObserver.kt +275 -0
  14. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/TracingState.kt +17 -0
  15. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/TracingStateListener.kt +15 -0
  16. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/{interfaces → inspector}/TracingStateProvider.kt +1 -1
  17. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorInspectorTargetBinding.kt +1 -1
  18. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorOverlayManager.kt +4 -4
  19. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorOverlayView.kt +3 -3
  20. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorUpdateListener.kt +1 -1
  21. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +13 -1
  22. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +21 -1
  23. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +5 -1
  24. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +5 -1
  25. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +23 -1
  26. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +5 -1
  27. package/ReactAndroid/src/main/java/com/facebook/react/internal/tracing/PerformanceTracer.kt +39 -0
  28. package/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BlobModule.kt +1 -1
  29. package/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkEventUtil.kt +20 -19
  30. package/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.kt +6 -12
  31. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
  32. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt +86 -4
  33. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImplDevHelper.kt +3 -3
  34. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostInspectorTarget.kt +10 -6
  35. package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.cpp +22 -0
  36. package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.h +2 -0
  37. package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +29 -1
  38. package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +7 -1
  39. package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.cpp +196 -17
  40. package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.h +168 -18
  41. package/ReactAndroid/src/main/jni/third-party/folly/CMakeLists.txt +1 -0
  42. package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
  43. package/ReactCommon/jsinspector-modern/HostAgent.cpp +45 -10
  44. package/ReactCommon/jsinspector-modern/HostAgent.h +2 -2
  45. package/ReactCommon/jsinspector-modern/HostTarget.cpp +14 -7
  46. package/ReactCommon/jsinspector-modern/HostTarget.h +101 -14
  47. package/ReactCommon/jsinspector-modern/HostTargetTraceRecording.cpp +39 -8
  48. package/ReactCommon/jsinspector-modern/HostTargetTraceRecording.h +42 -5
  49. package/ReactCommon/jsinspector-modern/HostTargetTracing.cpp +54 -21
  50. package/ReactCommon/jsinspector-modern/HostTargetTracing.h +89 -0
  51. package/ReactCommon/jsinspector-modern/InspectorFlags.cpp +12 -0
  52. package/ReactCommon/jsinspector-modern/InspectorFlags.h +12 -0
  53. package/ReactCommon/jsinspector-modern/InspectorInterfaces.cpp +3 -7
  54. package/ReactCommon/jsinspector-modern/InstanceAgent.cpp +2 -11
  55. package/ReactCommon/jsinspector-modern/NetworkIOAgent.cpp +1 -1
  56. package/ReactCommon/jsinspector-modern/TracingAgent.cpp +29 -13
  57. package/ReactCommon/jsinspector-modern/TracingAgent.h +5 -4
  58. package/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp +65 -0
  59. package/ReactCommon/jsinspector-modern/tests/InspectorMocks.h +23 -2
  60. package/ReactCommon/jsinspector-modern/tests/JsiIntegrationTest.cpp +1 -0
  61. package/ReactCommon/jsinspector-modern/tests/NetworkReporterTest.cpp +1 -0
  62. package/ReactCommon/jsinspector-modern/tests/TracingTest.cpp +335 -0
  63. package/ReactCommon/jsinspector-modern/tests/TracingTest.h +95 -0
  64. package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.cpp +10 -0
  65. package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.h +3 -1
  66. package/ReactCommon/jsinspector-modern/tracing/CMakeLists.txt +1 -0
  67. package/ReactCommon/jsinspector-modern/tracing/FrameTimingSequence.h +61 -0
  68. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfile.h +43 -0
  69. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.cpp +165 -0
  70. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.h +50 -0
  71. package/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp +16 -14
  72. package/ReactCommon/jsinspector-modern/tracing/PerformanceTracerSection.h +113 -0
  73. package/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec +1 -0
  74. package/ReactCommon/jsinspector-modern/tracing/TimeWindowedBuffer.h +158 -0
  75. package/ReactCommon/jsinspector-modern/tracing/TraceEvent.h +2 -1
  76. package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.cpp +100 -0
  77. package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.h +60 -0
  78. package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.cpp +44 -1
  79. package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.h +7 -0
  80. package/ReactCommon/jsinspector-modern/tracing/TraceRecordingState.h +18 -7
  81. package/ReactCommon/jsinspector-modern/tracing/TracingCategory.h +136 -0
  82. package/ReactCommon/jsinspector-modern/tracing/tests/TimeWindowedBufferTest.cpp +352 -0
  83. package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +9 -1
  84. package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +11 -1
  85. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +65 -29
  86. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +6 -2
  87. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +9 -1
  88. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +19 -1
  89. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +3 -1
  90. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +3 -1
  91. package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +11 -1
  92. package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +5 -1
  93. package/ReactCommon/react/performance/timeline/PerformanceObserver.cpp +18 -6
  94. package/ReactCommon/react/performance/timeline/PerformanceObserver.h +2 -0
  95. package/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm +115 -0
  96. package/ReactCommon/{jsinspector-modern → react/utils}/Base64.h +2 -2
  97. package/gradle/libs.versions.toml +1 -1
  98. package/package.json +8 -8
  99. package/scripts/cocoapods/utils.rb +1 -0
  100. package/src/private/featureflags/ReactNativeFeatureFlags.js +11 -1
  101. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +3 -1
  102. package/third-party-podspecs/RCT-Folly.podspec +1 -1
  103. package/third-party-podspecs/fmt.podspec +2 -2
  104. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/TracingState.kt +0 -19
  105. package/ReactCommon/jsinspector-modern/tracing/TraceRecordingStateSerializer.cpp +0 -68
  106. package/ReactCommon/jsinspector-modern/tracing/TraceRecordingStateSerializer.h +0 -42
  107. package/ReactCommon/jsinspector-modern/tracing/TracingState.h +0 -24
@@ -28,7 +28,7 @@
28
28
  export default class ReactNativeVersion {
29
29
  static major: number = 0;
30
30
  static minor: number = 83;
31
- static patch: number = 4;
31
+ static patch: number = 5;
32
32
  static prerelease: string | null = null;
33
33
 
34
34
  static getVersionString(): string {
@@ -99,7 +99,12 @@ export function setColorScheme(colorScheme: ColorSchemeName): void {
99
99
  if (NativeAppearance != null) {
100
100
  NativeAppearance.setColorScheme(colorScheme);
101
101
  state.appearance = {
102
- colorScheme,
102
+ // When setting to 'unspecified', get the actual system color scheme.
103
+ // Fall back to the passed value if getColorScheme() returns null.
104
+ colorScheme:
105
+ colorScheme === 'unspecified'
106
+ ? (NativeAppearance.getColorScheme() ?? colorScheme)
107
+ : colorScheme,
103
108
  };
104
109
  }
105
110
  }
@@ -23,7 +23,7 @@ NSDictionary* RCTGetReactNativeVersion(void)
23
23
  __rnVersion = @{
24
24
  RCTVersionMajor: @(0),
25
25
  RCTVersionMinor: @(83),
26
- RCTVersionPatch: @(4),
26
+ RCTVersionPatch: @(5),
27
27
  RCTVersionPrerelease: [NSNull null],
28
28
  };
29
29
  });
@@ -0,0 +1,24 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #import <Foundation/Foundation.h>
9
+
10
+ #ifdef __cplusplus
11
+ #import <jsinspector-modern/tracing/FrameTimingSequence.h>
12
+
13
+ using RCTFrameTimingCallback = void (^)(facebook::react::jsinspector_modern::tracing::FrameTimingSequence);
14
+ #endif
15
+
16
+ @interface RCTFrameTimingsObserver : NSObject
17
+
18
+ #ifdef __cplusplus
19
+ - (instancetype)initWithScreenshotsEnabled:(BOOL)screenshotsEnabled callback:(RCTFrameTimingCallback)callback;
20
+ #endif
21
+ - (void)start;
22
+ - (void)stop;
23
+
24
+ @end
@@ -0,0 +1,298 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #import "RCTFrameTimingsObserver.h"
9
+
10
+ #import <UIKit/UIKit.h>
11
+
12
+ #import <mach/thread_act.h>
13
+ #import <pthread.h>
14
+
15
+ #import <atomic>
16
+ #import <chrono>
17
+ #import <mutex>
18
+ #import <optional>
19
+ #import <vector>
20
+
21
+ #import <react/timing/primitives.h>
22
+
23
+ using namespace facebook::react;
24
+
25
+ static constexpr CGFloat kScreenshotScaleFactor = 1.0;
26
+ static constexpr CGFloat kScreenshotJPEGQuality = 0.8;
27
+
28
+ namespace {
29
+
30
+ // Stores a captured frame screenshot and its associated metadata, used for
31
+ // buffering frames during dynamic sampling.
32
+ struct FrameData {
33
+ UIImage *image;
34
+ uint64_t frameId;
35
+ jsinspector_modern::tracing::ThreadId threadId;
36
+ HighResTimeStamp beginTimestamp;
37
+ HighResTimeStamp endTimestamp;
38
+ };
39
+
40
+ } // namespace
41
+
42
+ @implementation RCTFrameTimingsObserver {
43
+ BOOL _screenshotsEnabled;
44
+ RCTFrameTimingCallback _callback;
45
+ CADisplayLink *_displayLink;
46
+ uint64_t _frameCounter;
47
+ // Serial queue for encoding work (single background thread). We limit to 1
48
+ // thread to minimize the performance impact of screenshot recording.
49
+ dispatch_queue_t _encodingQueue;
50
+ std::atomic<bool> _running;
51
+ uint64_t _lastScreenshotHash;
52
+
53
+ // Stores the most recently captured frame to opportunistically encode after
54
+ // the current frame. Replaced frames are emitted as timings without
55
+ // screenshots.
56
+ std::mutex _lastFrameMutex;
57
+ std::optional<FrameData> _lastFrameData;
58
+
59
+ std::atomic<bool> _encodingInProgress;
60
+ }
61
+
62
+ - (instancetype)initWithScreenshotsEnabled:(BOOL)screenshotsEnabled callback:(RCTFrameTimingCallback)callback
63
+ {
64
+ if (self = [super init]) {
65
+ _screenshotsEnabled = screenshotsEnabled;
66
+ _callback = [callback copy];
67
+ _frameCounter = 0;
68
+ _encodingQueue = dispatch_queue_create("com.facebook.react.frame-timings-observer", DISPATCH_QUEUE_SERIAL);
69
+ _running.store(false);
70
+ _lastScreenshotHash = 0;
71
+ _encodingInProgress.store(false);
72
+ }
73
+ return self;
74
+ }
75
+
76
+ - (void)start
77
+ {
78
+ _running.store(true, std::memory_order_relaxed);
79
+ _frameCounter = 0;
80
+ _lastScreenshotHash = 0;
81
+ _encodingInProgress.store(false, std::memory_order_relaxed);
82
+ {
83
+ std::lock_guard<std::mutex> lock(_lastFrameMutex);
84
+ _lastFrameData.reset();
85
+ }
86
+
87
+ // Emit initial frame event
88
+ auto now = HighResTimeStamp::now();
89
+ [self _emitFrameTimingWithBeginTimestamp:now endTimestamp:now];
90
+
91
+ _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(_displayLinkTick:)];
92
+ [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
93
+ }
94
+
95
+ - (void)stop
96
+ {
97
+ _running.store(false, std::memory_order_relaxed);
98
+ [_displayLink invalidate];
99
+ _displayLink = nil;
100
+ {
101
+ std::lock_guard<std::mutex> lock(_lastFrameMutex);
102
+ _lastFrameData.reset();
103
+ }
104
+ }
105
+
106
+ - (void)_displayLinkTick:(CADisplayLink *)sender
107
+ {
108
+ // CADisplayLink.timestamp and targetTimestamp are in the same timebase as
109
+ // CACurrentMediaTime() / mach_absolute_time(), which on Apple platforms maps
110
+ // to CLOCK_UPTIME_RAW — the same clock backing std::chrono::steady_clock.
111
+ auto beginNanos = static_cast<int64_t>(sender.timestamp * 1e9);
112
+ auto endNanos = static_cast<int64_t>(sender.targetTimestamp * 1e9);
113
+
114
+ auto beginTimestamp = HighResTimeStamp::fromChronoSteadyClockTimePoint(
115
+ std::chrono::steady_clock::time_point(std::chrono::nanoseconds(beginNanos)));
116
+ auto endTimestamp = HighResTimeStamp::fromChronoSteadyClockTimePoint(
117
+ std::chrono::steady_clock::time_point(std::chrono::nanoseconds(endNanos)));
118
+
119
+ [self _emitFrameTimingWithBeginTimestamp:beginTimestamp endTimestamp:endTimestamp];
120
+ }
121
+
122
+ - (void)_emitFrameTimingWithBeginTimestamp:(HighResTimeStamp)beginTimestamp endTimestamp:(HighResTimeStamp)endTimestamp
123
+ {
124
+ uint64_t frameId = _frameCounter++;
125
+ auto threadId = static_cast<jsinspector_modern::tracing::ThreadId>(pthread_mach_thread_np(pthread_self()));
126
+
127
+ if (!_screenshotsEnabled) {
128
+ // Screenshots disabled - emit without screenshot
129
+ [self _emitFrameEventWithFrameId:frameId
130
+ threadId:threadId
131
+ beginTimestamp:beginTimestamp
132
+ endTimestamp:endTimestamp
133
+ screenshot:std::nullopt];
134
+ return;
135
+ }
136
+
137
+ UIImage *image = [self _captureScreenshot];
138
+ if (image == nil) {
139
+ // Failed to capture (e.g. no window, duplicate hash) - emit without screenshot
140
+ [self _emitFrameEventWithFrameId:frameId
141
+ threadId:threadId
142
+ beginTimestamp:beginTimestamp
143
+ endTimestamp:endTimestamp
144
+ screenshot:std::nullopt];
145
+ return;
146
+ }
147
+
148
+ FrameData frameData{image, frameId, threadId, beginTimestamp, endTimestamp};
149
+
150
+ bool expected = false;
151
+ if (_encodingInProgress.compare_exchange_strong(expected, true)) {
152
+ // Not encoding - encode this frame immediately
153
+ [self _encodeFrame:std::move(frameData)];
154
+ } else {
155
+ // Encoding thread busy - store current screenshot in buffer for tail-capture
156
+ std::optional<FrameData> oldFrame;
157
+ {
158
+ std::lock_guard<std::mutex> lock(_lastFrameMutex);
159
+ oldFrame = std::move(_lastFrameData);
160
+ _lastFrameData = std::move(frameData);
161
+ }
162
+ if (oldFrame.has_value()) {
163
+ // Skipped frame - emit event without screenshot
164
+ [self _emitFrameEventWithFrameId:oldFrame->frameId
165
+ threadId:oldFrame->threadId
166
+ beginTimestamp:oldFrame->beginTimestamp
167
+ endTimestamp:oldFrame->endTimestamp
168
+ screenshot:std::nullopt];
169
+ }
170
+ }
171
+ }
172
+
173
+ - (void)_emitFrameEventWithFrameId:(uint64_t)frameId
174
+ threadId:(jsinspector_modern::tracing::ThreadId)threadId
175
+ beginTimestamp:(HighResTimeStamp)beginTimestamp
176
+ endTimestamp:(HighResTimeStamp)endTimestamp
177
+ screenshot:(std::optional<std::vector<uint8_t>>)screenshot
178
+ {
179
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
180
+ if (!self->_running.load(std::memory_order_relaxed)) {
181
+ return;
182
+ }
183
+ jsinspector_modern::tracing::FrameTimingSequence sequence{
184
+ frameId, threadId, beginTimestamp, endTimestamp, std::move(screenshot)};
185
+ self->_callback(std::move(sequence));
186
+ });
187
+ }
188
+
189
+ - (void)_encodeFrame:(FrameData)frameData
190
+ {
191
+ dispatch_async(_encodingQueue, ^{
192
+ if (!self->_running.load(std::memory_order_relaxed)) {
193
+ return;
194
+ }
195
+
196
+ auto screenshot = [self _encodeScreenshot:frameData.image];
197
+ [self _emitFrameEventWithFrameId:frameData.frameId
198
+ threadId:frameData.threadId
199
+ beginTimestamp:frameData.beginTimestamp
200
+ endTimestamp:frameData.endTimestamp
201
+ screenshot:std::move(screenshot)];
202
+
203
+ // Clear encoding flag early, allowing new frames to start fresh encoding
204
+ // sessions
205
+ self->_encodingInProgress.store(false, std::memory_order_release);
206
+
207
+ // Opportunistically encode tail frame (if present) without blocking new
208
+ // frames
209
+ std::optional<FrameData> tailFrame;
210
+ {
211
+ std::lock_guard<std::mutex> lock(self->_lastFrameMutex);
212
+ tailFrame = std::move(self->_lastFrameData);
213
+ self->_lastFrameData.reset();
214
+ }
215
+ if (tailFrame.has_value()) {
216
+ if (!self->_running.load(std::memory_order_relaxed)) {
217
+ return;
218
+ }
219
+ auto tailScreenshot = [self _encodeScreenshot:tailFrame->image];
220
+ [self _emitFrameEventWithFrameId:tailFrame->frameId
221
+ threadId:tailFrame->threadId
222
+ beginTimestamp:tailFrame->beginTimestamp
223
+ endTimestamp:tailFrame->endTimestamp
224
+ screenshot:std::move(tailScreenshot)];
225
+ }
226
+ });
227
+ }
228
+
229
+ // Captures a screenshot of the current window. Must be called on the main
230
+ // thread. Returns nil if capture fails or if the frame content is unchanged.
231
+ - (UIImage *)_captureScreenshot
232
+ {
233
+ UIWindow *keyWindow = [self _getKeyWindow];
234
+ if (keyWindow == nil) {
235
+ return nil;
236
+ }
237
+
238
+ UIView *rootView = keyWindow.rootViewController.view ?: keyWindow;
239
+ CGSize viewSize = rootView.bounds.size;
240
+ CGSize scaledSize = CGSizeMake(viewSize.width * kScreenshotScaleFactor, viewSize.height * kScreenshotScaleFactor);
241
+
242
+ UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat defaultFormat];
243
+ format.scale = 1.0;
244
+ UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:scaledSize format:format];
245
+
246
+ UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext *context) {
247
+ [rootView drawViewHierarchyInRect:CGRectMake(0, 0, scaledSize.width, scaledSize.height) afterScreenUpdates:NO];
248
+ }];
249
+
250
+ // Skip duplicate frames via sampled FNV-1a pixel hash
251
+ CGImageRef cgImage = image.CGImage;
252
+ CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(cgImage));
253
+ uint64_t hash = 0xcbf29ce484222325ULL;
254
+ const uint8_t *ptr = CFDataGetBytePtr(pixelData);
255
+ CFIndex length = CFDataGetLength(pixelData);
256
+ // Use prime stride to prevent row alignment on power-of-2 pixel widths
257
+ for (CFIndex i = 0; i < length; i += 67) {
258
+ hash ^= ptr[i];
259
+ hash *= 0x100000001b3ULL;
260
+ }
261
+ CFRelease(pixelData);
262
+
263
+ if (hash == _lastScreenshotHash) {
264
+ return nil;
265
+ }
266
+ _lastScreenshotHash = hash;
267
+
268
+ return image;
269
+ }
270
+
271
+ - (std::optional<std::vector<uint8_t>>)_encodeScreenshot:(UIImage *)image
272
+ {
273
+ NSData *jpegData = UIImageJPEGRepresentation(image, kScreenshotJPEGQuality);
274
+ if (jpegData == nil) {
275
+ return std::nullopt;
276
+ }
277
+
278
+ const auto *bytes = static_cast<const uint8_t *>(jpegData.bytes);
279
+ return std::vector<uint8_t>(bytes, bytes + jpegData.length);
280
+ }
281
+
282
+ - (UIWindow *)_getKeyWindow
283
+ {
284
+ for (UIScene *scene in UIApplication.sharedApplication.connectedScenes) {
285
+ if (scene.activationState == UISceneActivationStateForegroundActive &&
286
+ [scene isKindOfClass:[UIWindowScene class]]) {
287
+ auto windowScene = (UIWindowScene *)scene;
288
+ for (UIWindow *window = nullptr in windowScene.windows) {
289
+ if (window.isKeyWindow) {
290
+ return window;
291
+ }
292
+ }
293
+ }
294
+ }
295
+ return nil;
296
+ }
297
+
298
+ @end
@@ -281,7 +281,9 @@ protected:
281
281
  methodMap_["fixMappingOfEventPrioritiesBetweenFabricAndReact"] = MethodMetadata {.argCount = 0, .invoker = __fixMappingOfEventPrioritiesBetweenFabricAndReact};
282
282
  methodMap_["fuseboxAssertSingleHostState"] = MethodMetadata {.argCount = 0, .invoker = __fuseboxAssertSingleHostState};
283
283
  methodMap_["fuseboxEnabledRelease"] = MethodMetadata {.argCount = 0, .invoker = __fuseboxEnabledRelease};
284
+ methodMap_["fuseboxFrameRecordingEnabled"] = MethodMetadata {.argCount = 0, .invoker = __fuseboxFrameRecordingEnabled};
284
285
  methodMap_["fuseboxNetworkInspectionEnabled"] = MethodMetadata {.argCount = 0, .invoker = __fuseboxNetworkInspectionEnabled};
286
+ methodMap_["fuseboxScreenshotCaptureEnabled"] = MethodMetadata {.argCount = 0, .invoker = __fuseboxScreenshotCaptureEnabled};
285
287
  methodMap_["hideOffscreenVirtualViewsOnIOS"] = MethodMetadata {.argCount = 0, .invoker = __hideOffscreenVirtualViewsOnIOS};
286
288
  methodMap_["overrideBySynchronousMountPropsAtMountingAndroid"] = MethodMetadata {.argCount = 0, .invoker = __overrideBySynchronousMountPropsAtMountingAndroid};
287
289
  methodMap_["perfIssuesEnabled"] = MethodMetadata {.argCount = 0, .invoker = __perfIssuesEnabled};
@@ -718,6 +720,13 @@ private:
718
720
  return bridging::callFromJs<bool>(rt, &T::fuseboxEnabledRelease, static_cast<NativeReactNativeFeatureFlagsCxxSpec*>(&turboModule)->jsInvoker_, static_cast<T*>(&turboModule));
719
721
  }
720
722
 
723
+ static jsi::Value __fuseboxFrameRecordingEnabled(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* /*args*/, size_t /*count*/) {
724
+ static_assert(
725
+ bridging::getParameterCount(&T::fuseboxFrameRecordingEnabled) == 1,
726
+ "Expected fuseboxFrameRecordingEnabled(...) to have 1 parameters");
727
+ return bridging::callFromJs<bool>(rt, &T::fuseboxFrameRecordingEnabled, static_cast<NativeReactNativeFeatureFlagsCxxSpec*>(&turboModule)->jsInvoker_, static_cast<T*>(&turboModule));
728
+ }
729
+
721
730
  static jsi::Value __fuseboxNetworkInspectionEnabled(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* /*args*/, size_t /*count*/) {
722
731
  static_assert(
723
732
  bridging::getParameterCount(&T::fuseboxNetworkInspectionEnabled) == 1,
@@ -725,6 +734,13 @@ private:
725
734
  return bridging::callFromJs<bool>(rt, &T::fuseboxNetworkInspectionEnabled, static_cast<NativeReactNativeFeatureFlagsCxxSpec*>(&turboModule)->jsInvoker_, static_cast<T*>(&turboModule));
726
735
  }
727
736
 
737
+ static jsi::Value __fuseboxScreenshotCaptureEnabled(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* /*args*/, size_t /*count*/) {
738
+ static_assert(
739
+ bridging::getParameterCount(&T::fuseboxScreenshotCaptureEnabled) == 1,
740
+ "Expected fuseboxScreenshotCaptureEnabled(...) to have 1 parameters");
741
+ return bridging::callFromJs<bool>(rt, &T::fuseboxScreenshotCaptureEnabled, static_cast<NativeReactNativeFeatureFlagsCxxSpec*>(&turboModule)->jsInvoker_, static_cast<T*>(&turboModule));
742
+ }
743
+
728
744
  static jsi::Value __hideOffscreenVirtualViewsOnIOS(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* /*args*/, size_t /*count*/) {
729
745
  static_assert(
730
746
  bridging::getParameterCount(&T::hideOffscreenVirtualViewsOnIOS) == 1,
@@ -2257,15 +2257,6 @@ public abstract interface class com/facebook/react/devsupport/interfaces/StackFr
2257
2257
  public abstract fun toJSON ()Lorg/json/JSONObject;
2258
2258
  }
2259
2259
 
2260
- public final class com/facebook/react/devsupport/interfaces/TracingState : java/lang/Enum {
2261
- public static final field DISABLED Lcom/facebook/react/devsupport/interfaces/TracingState;
2262
- public static final field ENABLEDINBACKGROUNDMODE Lcom/facebook/react/devsupport/interfaces/TracingState;
2263
- public static final field ENABLEDINCDPMODE Lcom/facebook/react/devsupport/interfaces/TracingState;
2264
- public static fun getEntries ()Lkotlin/enums/EnumEntries;
2265
- public static fun valueOf (Ljava/lang/String;)Lcom/facebook/react/devsupport/interfaces/TracingState;
2266
- public static fun values ()[Lcom/facebook/react/devsupport/interfaces/TracingState;
2267
- }
2268
-
2269
2260
  public final class com/facebook/react/fabric/ComponentFactory {
2270
2261
  public fun <init> ()V
2271
2262
  }
@@ -1,4 +1,4 @@
1
- VERSION_NAME=0.83.4
1
+ VERSION_NAME=0.83.5
2
2
  react.internal.publishingGroup=com.facebook.react
3
3
  react.internal.hermesPublishingGroup=com.facebook.hermes
4
4
 
@@ -10,12 +10,12 @@ package com.facebook.react.devsupport
10
10
  import android.content.Context
11
11
  import com.facebook.react.bridge.UiThreadUtil
12
12
  import com.facebook.react.common.SurfaceDelegateFactory
13
+ import com.facebook.react.devsupport.inspector.TracingState
13
14
  import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener
14
15
  import com.facebook.react.devsupport.interfaces.DevLoadingViewManager
15
16
  import com.facebook.react.devsupport.interfaces.DevSupportManager
16
17
  import com.facebook.react.devsupport.interfaces.PausedInDebuggerOverlayManager
17
18
  import com.facebook.react.devsupport.interfaces.RedBoxHandler
18
- import com.facebook.react.devsupport.interfaces.TracingState
19
19
  import com.facebook.react.packagerconnection.RequestHandler
20
20
 
21
21
  /**
@@ -83,6 +83,6 @@ internal class BridgelessDevSupportManager(
83
83
  }
84
84
 
85
85
  fun tracingState(): TracingState {
86
- return TracingState.ENABLEDINCDPMODE
86
+ return TracingState.ENABLED_IN_CDP_MODE
87
87
  }
88
88
  }
@@ -52,6 +52,8 @@ import com.facebook.react.devsupport.DevServerHelper.PackagerCommandListener
52
52
  import com.facebook.react.devsupport.InspectorFlags.getFuseboxEnabled
53
53
  import com.facebook.react.devsupport.StackTraceHelper.convertJavaStackTrace
54
54
  import com.facebook.react.devsupport.StackTraceHelper.convertJsStackTrace
55
+ import com.facebook.react.devsupport.inspector.TracingState
56
+ import com.facebook.react.devsupport.inspector.TracingStateProvider
55
57
  import com.facebook.react.devsupport.interfaces.BundleLoadCallback
56
58
  import com.facebook.react.devsupport.interfaces.DebuggerFrontendPanelName
57
59
  import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener
@@ -66,8 +68,6 @@ import com.facebook.react.devsupport.interfaces.PackagerStatusCallback
66
68
  import com.facebook.react.devsupport.interfaces.PausedInDebuggerOverlayManager
67
69
  import com.facebook.react.devsupport.interfaces.RedBoxHandler
68
70
  import com.facebook.react.devsupport.interfaces.StackFrame
69
- import com.facebook.react.devsupport.interfaces.TracingState
70
- import com.facebook.react.devsupport.interfaces.TracingStateProvider
71
71
  import com.facebook.react.devsupport.perfmonitor.PerfMonitorDevHelper
72
72
  import com.facebook.react.devsupport.perfmonitor.PerfMonitorOverlayManager
73
73
  import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
@@ -396,21 +396,21 @@ public abstract class DevSupportManagerBase(
396
396
 
397
397
  val analyzePerformanceItemString =
398
398
  when (tracingState) {
399
- TracingState.ENABLEDINBACKGROUNDMODE ->
399
+ TracingState.ENABLED_IN_BACKGROUND_MODE ->
400
400
  applicationContext.getString(R.string.catalyst_performance_background)
401
- TracingState.ENABLEDINCDPMODE ->
401
+ TracingState.ENABLED_IN_CDP_MODE ->
402
402
  applicationContext.getString(R.string.catalyst_performance_cdp)
403
403
  TracingState.DISABLED ->
404
404
  applicationContext.getString(R.string.catalyst_performance_disabled)
405
405
  }
406
406
 
407
- if (!isConnected || tracingState == TracingState.ENABLEDINCDPMODE) {
407
+ if (!isConnected || tracingState == TracingState.ENABLED_IN_CDP_MODE) {
408
408
  disabledItemKeys.add(analyzePerformanceItemString)
409
409
  }
410
410
 
411
411
  options[analyzePerformanceItemString] =
412
412
  when (tracingState) {
413
- TracingState.ENABLEDINBACKGROUNDMODE ->
413
+ TracingState.ENABLED_IN_BACKGROUND_MODE ->
414
414
  DevOptionHandler {
415
415
  UiThreadUtil.runOnUiThread {
416
416
  if (reactInstanceDevHelper is PerfMonitorDevHelper) {
@@ -427,7 +427,7 @@ public abstract class DevSupportManagerBase(
427
427
  if (reactInstanceDevHelper is PerfMonitorDevHelper)
428
428
  reactInstanceDevHelper.inspectorTarget?.resumeBackgroundTrace()
429
429
  }
430
- TracingState.ENABLEDINCDPMODE -> DevOptionHandler {}
430
+ TracingState.ENABLED_IN_CDP_MODE -> DevOptionHandler {}
431
431
  }
432
432
  }
433
433
 
@@ -17,7 +17,11 @@ internal object InspectorFlags {
17
17
  SoLoader.loadLibrary("react_devsupportjni")
18
18
  }
19
19
 
20
+ @DoNotStrip @JvmStatic external fun getScreenshotCaptureEnabled(): Boolean
21
+
20
22
  @DoNotStrip @JvmStatic external fun getFuseboxEnabled(): Boolean
21
23
 
22
24
  @DoNotStrip @JvmStatic external fun getIsProfilingBuild(): Boolean
25
+
26
+ @DoNotStrip @JvmStatic external fun getFrameRecordingEnabled(): Boolean
23
27
  }
@@ -0,0 +1,16 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.devsupport.inspector
9
+
10
+ internal data class FrameTimingSequence(
11
+ val id: Int,
12
+ val threadId: Int,
13
+ val beginTimestamp: Long,
14
+ val endTimestamp: Long,
15
+ val screenshot: ByteArray? = null,
16
+ )