react-native-tvos 0.74.2-0 → 0.74.3-0
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.
- package/Libraries/AppDelegate/RCTAppDelegate.mm +4 -1
- package/Libraries/AppDelegate/RCTRootViewFactory.h +8 -0
- package/Libraries/AppDelegate/RCTRootViewFactory.mm +11 -3
- package/Libraries/Components/Pressable/Pressable.js +2 -2
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Text/TextInput/Multiline/RCTUITextView.mm +6 -0
- package/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +1 -0
- package/Libraries/Text/TextInput/Singleline/RCTUITextField.mm +5 -0
- package/React/Base/RCTVersion.m +1 -1
- package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +10 -5
- package/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +4 -0
- package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +3 -2
- package/React/Views/ScrollView/RCTScrollView.m +4 -4
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +2 -4
- package/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java +5 -2
- package/ReactAndroid/src/main/java/com/facebook/react/modules/core/ReactAndroidHWInputDeviceHelper.java +20 -0
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java +3 -1
- package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactSurfaceView.java +5 -0
- package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
- package/ReactCommon/jsc/JSCRuntime.cpp +30 -2
- package/ReactCommon/jsi/jsi/decorator.h +7 -0
- package/ReactCommon/jsi/jsi/jsi.h +7 -0
- package/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp +53 -10
- package/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp +0 -1
- package/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Legacy.cpp +3 -3
- package/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp +28 -28
- package/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.h +3 -3
- package/ReactCommon/react/renderer/runtimescheduler/Task.cpp +9 -7
- package/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp +46 -0
- package/package.json +13 -13
- package/scripts/codegen/generate-artifacts-executor.js +1 -1
- package/sdks/.hermesversion +1 -1
- package/sdks/hermesc/osx-bin/hermes +0 -0
- package/sdks/hermesc/osx-bin/hermesc +0 -0
- package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
- package/template/package.json +6 -6
- package/ReactCommon/react/renderer/runtimescheduler/ErrorUtils.h +0 -34
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
|
|
66
66
|
}
|
|
67
67
|
[self _logWarnIfCreateRootViewWithBridgeIsOverridden];
|
|
68
|
-
[self customizeRootView:(RCTRootView *)rootView];
|
|
69
68
|
|
|
70
69
|
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
|
71
70
|
UIViewController *rootViewController = [self createRootViewController];
|
|
@@ -271,6 +270,10 @@
|
|
|
271
270
|
return [weakSelf createBridgeWithDelegate:delegate launchOptions:launchOptions];
|
|
272
271
|
};
|
|
273
272
|
|
|
273
|
+
configuration.customizeRootView = ^(UIView *_Nonnull rootView) {
|
|
274
|
+
[weakSelf customizeRootView:(RCTRootView *)rootView];
|
|
275
|
+
};
|
|
276
|
+
|
|
274
277
|
return [[RCTRootViewFactory alloc] initWithConfiguration:configuration andTurboModuleManagerDelegate:self];
|
|
275
278
|
}
|
|
276
279
|
|
|
@@ -23,6 +23,7 @@ typedef UIView *_Nonnull (
|
|
|
23
23
|
^RCTCreateRootViewWithBridgeBlock)(RCTBridge *bridge, NSString *moduleName, NSDictionary *initProps);
|
|
24
24
|
typedef RCTBridge *_Nonnull (
|
|
25
25
|
^RCTCreateBridgeWithDelegateBlock)(id<RCTBridgeDelegate> delegate, NSDictionary *launchOptions);
|
|
26
|
+
typedef void (^RCTCustomizeRootViewBlock)(UIView *rootView);
|
|
26
27
|
typedef NSURL *_Nullable (^RCTSourceURLForBridgeBlock)(RCTBridge *bridge);
|
|
27
28
|
typedef NSURL *_Nullable (^RCTBundleURLBlock)(void);
|
|
28
29
|
typedef NSArray<id<RCTBridgeModule>> *_Nonnull (^RCTExtraModulesForBridgeBlock)(RCTBridge *bridge);
|
|
@@ -91,6 +92,13 @@ typedef BOOL (^RCTBridgeDidNotFindModuleBlock)(RCTBridge *bridge, NSString *modu
|
|
|
91
92
|
*/
|
|
92
93
|
@property (nonatomic, nullable) RCTCreateBridgeWithDelegateBlock createBridgeWithDelegate;
|
|
93
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Block that allows to customize the rootView that is passed to React Native.
|
|
97
|
+
*
|
|
98
|
+
* @parameter: rootView - The root view to customize.
|
|
99
|
+
*/
|
|
100
|
+
@property (nonatomic, nullable) RCTCustomizeRootViewBlock customizeRootView;
|
|
101
|
+
|
|
94
102
|
@end
|
|
95
103
|
|
|
96
104
|
#pragma mark - RCTRootViewFactory
|
|
@@ -145,17 +145,25 @@ static NSDictionary *updateInitialProps(NSDictionary *initialProps, BOOL isFabri
|
|
|
145
145
|
initWithSurface:surface
|
|
146
146
|
sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact];
|
|
147
147
|
|
|
148
|
+
if (self->_configuration.customizeRootView != nil) {
|
|
149
|
+
self->_configuration.customizeRootView(surfaceHostingProxyRootView);
|
|
150
|
+
}
|
|
148
151
|
return surfaceHostingProxyRootView;
|
|
149
152
|
}
|
|
150
153
|
|
|
151
154
|
[self createBridgeIfNeeded:launchOptions];
|
|
152
155
|
[self createBridgeAdapterIfNeeded];
|
|
153
156
|
|
|
157
|
+
UIView *rootView;
|
|
154
158
|
if (self->_configuration.createRootViewWithBridge != nil) {
|
|
155
|
-
|
|
159
|
+
rootView = self->_configuration.createRootViewWithBridge(self.bridge, moduleName, initProps);
|
|
160
|
+
} else {
|
|
161
|
+
rootView = [self createRootViewWithBridge:self.bridge moduleName:moduleName initProps:initProps];
|
|
156
162
|
}
|
|
157
|
-
|
|
158
|
-
|
|
163
|
+
if (self->_configuration.customizeRootView != nil) {
|
|
164
|
+
self->_configuration.customizeRootView(rootView);
|
|
165
|
+
}
|
|
166
|
+
return rootView;
|
|
159
167
|
}
|
|
160
168
|
|
|
161
169
|
- (RCTBridge *)createBridgeWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions
|
|
@@ -393,12 +393,12 @@ function Pressable(props: Props, forwardedRef): React.Node {
|
|
|
393
393
|
}
|
|
394
394
|
}
|
|
395
395
|
// $FlowFixMe[prop-missing]
|
|
396
|
-
if (
|
|
396
|
+
if (evt.eventType === 'select') {
|
|
397
397
|
// $FlowFixMe[incompatible-exact]
|
|
398
398
|
onPress && onPress(evt);
|
|
399
399
|
}
|
|
400
400
|
// $FlowFixMe[prop-missing]
|
|
401
|
-
if (
|
|
401
|
+
if (evt.eventType === 'longSelect') {
|
|
402
402
|
// $FlowFixMe[incompatible-exact]
|
|
403
403
|
onLongPress && onLongPress(evt);
|
|
404
404
|
}
|
|
@@ -165,6 +165,12 @@ static UIColor *defaultPlaceholderColor(void)
|
|
|
165
165
|
[super setSelectedTextRange:selectedTextRange];
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
// After restoring the previous cursor position, we manually trigger the scroll to the new cursor position (PR 38679).
|
|
169
|
+
- (void)scrollRangeToVisible:(NSRange)range
|
|
170
|
+
{
|
|
171
|
+
[super scrollRangeToVisible:range];
|
|
172
|
+
}
|
|
173
|
+
|
|
168
174
|
- (void)paste:(id)sender
|
|
169
175
|
{
|
|
170
176
|
_textWasPasted = YES;
|
|
@@ -43,6 +43,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
43
43
|
// If the change was a result of user actions (like typing or touches), we MUST notify the delegate.
|
|
44
44
|
- (void)setSelectedTextRange:(nullable UITextRange *)selectedTextRange NS_UNAVAILABLE;
|
|
45
45
|
- (void)setSelectedTextRange:(nullable UITextRange *)selectedTextRange notifyDelegate:(BOOL)notifyDelegate;
|
|
46
|
+
- (void)scrollRangeToVisible:(NSRange)selectedTextRange;
|
|
46
47
|
|
|
47
48
|
// This protocol disallows direct access to `text` property because
|
|
48
49
|
// unwise usage of it can break the `attributeText` behavior.
|
|
@@ -201,6 +201,11 @@
|
|
|
201
201
|
[super setSelectedTextRange:selectedTextRange];
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
+
- (void)scrollRangeToVisible:(NSRange)range
|
|
205
|
+
{
|
|
206
|
+
// Singleline TextInput does not require scrolling after calling setSelectedTextRange (PR 38679).
|
|
207
|
+
}
|
|
208
|
+
|
|
204
209
|
- (void)paste:(id)sender
|
|
205
210
|
{
|
|
206
211
|
_textWasPasted = YES;
|
package/React/Base/RCTVersion.m
CHANGED
|
@@ -131,8 +131,8 @@ static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrol
|
|
|
131
131
|
{
|
|
132
132
|
if (self = [super initWithFrame:frame]) {
|
|
133
133
|
_props = ScrollViewShadowNode::defaultSharedProps();
|
|
134
|
-
|
|
135
134
|
_scrollView = [[RCTEnhancedScrollView alloc] initWithFrame:self.bounds];
|
|
135
|
+
_scrollView.clipsToBounds = _props->getClipsContentToBounds();
|
|
136
136
|
_scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
137
137
|
_scrollView.delaysContentTouches = NO;
|
|
138
138
|
((RCTEnhancedScrollView *)_scrollView).overridingDelegate = self;
|
|
@@ -270,6 +270,11 @@ static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrol
|
|
|
270
270
|
}
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
+
// Overflow prop
|
|
274
|
+
if (oldScrollViewProps.getClipsContentToBounds() != newScrollViewProps.getClipsContentToBounds()) {
|
|
275
|
+
_scrollView.clipsToBounds = newScrollViewProps.getClipsContentToBounds();
|
|
276
|
+
}
|
|
277
|
+
|
|
273
278
|
MAP_SCROLL_VIEW_PROP(zoomScale);
|
|
274
279
|
|
|
275
280
|
if (oldScrollViewProps.contentInset != newScrollViewProps.contentInset) {
|
|
@@ -1008,28 +1013,28 @@ static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrol
|
|
|
1008
1013
|
- (void)swipedUp
|
|
1009
1014
|
{
|
|
1010
1015
|
CGFloat newOffset = self.scrollView.contentOffset.y - [self swipeVerticalInterval];
|
|
1011
|
-
NSLog(@"Swiped up to %f", newOffset);
|
|
1016
|
+
// NSLog(@"Swiped up to %f", newOffset);
|
|
1012
1017
|
[self swipeVerticalScrollToOffset:newOffset];
|
|
1013
1018
|
}
|
|
1014
1019
|
|
|
1015
1020
|
- (void)swipedDown
|
|
1016
1021
|
{
|
|
1017
1022
|
CGFloat newOffset = self.scrollView.contentOffset.y + [self swipeVerticalInterval];
|
|
1018
|
-
NSLog(@"Swiped down to %f", newOffset);
|
|
1023
|
+
// NSLog(@"Swiped down to %f", newOffset);
|
|
1019
1024
|
[self swipeVerticalScrollToOffset:newOffset];
|
|
1020
1025
|
}
|
|
1021
1026
|
|
|
1022
1027
|
- (void)swipedLeft
|
|
1023
1028
|
{
|
|
1024
1029
|
CGFloat newOffset = self.scrollView.contentOffset.x - [self swipeHorizontalInterval];
|
|
1025
|
-
NSLog(@"Swiped left to %f", newOffset);
|
|
1030
|
+
// NSLog(@"Swiped left to %f", newOffset);
|
|
1026
1031
|
[self swipeHorizontalScrollToOffset:newOffset];
|
|
1027
1032
|
}
|
|
1028
1033
|
|
|
1029
1034
|
- (void)swipedRight
|
|
1030
1035
|
{
|
|
1031
1036
|
CGFloat newOffset = self.scrollView.contentOffset.x + [self swipeHorizontalInterval];
|
|
1032
|
-
NSLog(@"Swiped right to %f", newOffset);
|
|
1037
|
+
// NSLog(@"Swiped right to %f", newOffset);
|
|
1033
1038
|
[self swipeHorizontalScrollToOffset:newOffset];
|
|
1034
1039
|
}
|
|
1035
1040
|
|
|
@@ -597,6 +597,9 @@ using namespace facebook::react;
|
|
|
597
597
|
UITextRange *selectedRange = _backedTextInputView.selectedTextRange;
|
|
598
598
|
NSInteger oldTextLength = _backedTextInputView.attributedText.string.length;
|
|
599
599
|
_backedTextInputView.attributedText = attributedString;
|
|
600
|
+
// Updating the UITextView attributedText, for example changing the lineHeight, the color or adding
|
|
601
|
+
// a new paragraph with \n, causes the cursor to move to the end of the Text and scroll.
|
|
602
|
+
// This is fixed by restoring the cursor position and scrolling to that position (iOS issue 652653).
|
|
600
603
|
if (selectedRange.empty) {
|
|
601
604
|
// Maintaining a cursor position relative to the end of the old text.
|
|
602
605
|
NSInteger offsetStart = [_backedTextInputView offsetFromPosition:_backedTextInputView.beginningOfDocument
|
|
@@ -607,6 +610,7 @@ using namespace facebook::react;
|
|
|
607
610
|
offset:newOffset];
|
|
608
611
|
[_backedTextInputView setSelectedTextRange:[_backedTextInputView textRangeFromPosition:position toPosition:position]
|
|
609
612
|
notifyDelegate:YES];
|
|
613
|
+
[_backedTextInputView scrollRangeToVisible:NSMakeRange(offsetStart, 0)];
|
|
610
614
|
}
|
|
611
615
|
[self _restoreTextSelection];
|
|
612
616
|
_lastStringStateWasUpdatedWith = attributedString;
|
|
@@ -1278,8 +1278,9 @@ static RCTBorderStyle RCTBorderStyleFromBorderStyle(BorderStyle borderStyle)
|
|
|
1278
1278
|
// iOS draws borders in front of the content whereas CSS draws them behind
|
|
1279
1279
|
// the content. For this reason, only use iOS border drawing when clipping
|
|
1280
1280
|
// or when the border is hidden.
|
|
1281
|
-
borderMetrics.borderWidths.left == 0 ||
|
|
1282
|
-
colorComponentsFromColor(borderMetrics.borderColors.left).alpha == 0
|
|
1281
|
+
borderMetrics.borderWidths.left == 0 || self.clipsToBounds ||
|
|
1282
|
+
(colorComponentsFromColor(borderMetrics.borderColors.left).alpha == 0 &&
|
|
1283
|
+
(*borderMetrics.borderColors.left).getUIColor() != nullptr));
|
|
1283
1284
|
|
|
1284
1285
|
CGColorRef backgroundColor = [_backgroundColor resolvedColorWithTraitCollection:self.traitCollection].CGColor;
|
|
1285
1286
|
|
|
@@ -1154,7 +1154,7 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
|
|
|
1154
1154
|
}
|
|
1155
1155
|
|
|
1156
1156
|
CGFloat newOffset = self.scrollView.contentOffset.y - [self swipeVerticalInterval];
|
|
1157
|
-
NSLog(@"Swiped up to %f", newOffset);
|
|
1157
|
+
// NSLog(@"Swiped up to %f", newOffset);
|
|
1158
1158
|
[self scrollToVerticalOffset:newOffset];
|
|
1159
1159
|
}
|
|
1160
1160
|
|
|
@@ -1165,7 +1165,7 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
|
|
|
1165
1165
|
}
|
|
1166
1166
|
|
|
1167
1167
|
CGFloat newOffset = self.scrollView.contentOffset.y + [self swipeVerticalInterval];
|
|
1168
|
-
NSLog(@"Swiped down to %f", newOffset);
|
|
1168
|
+
// NSLog(@"Swiped down to %f", newOffset);
|
|
1169
1169
|
[self scrollToVerticalOffset:newOffset];
|
|
1170
1170
|
}
|
|
1171
1171
|
|
|
@@ -1176,7 +1176,7 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
|
|
|
1176
1176
|
}
|
|
1177
1177
|
|
|
1178
1178
|
CGFloat newOffset = self.scrollView.contentOffset.x - [self swipeHorizontalInterval];
|
|
1179
|
-
NSLog(@"Swiped left to %f", newOffset);
|
|
1179
|
+
// NSLog(@"Swiped left to %f", newOffset);
|
|
1180
1180
|
[self scrollToHorizontalOffset:newOffset];
|
|
1181
1181
|
}
|
|
1182
1182
|
|
|
@@ -1187,7 +1187,7 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
|
|
|
1187
1187
|
}
|
|
1188
1188
|
|
|
1189
1189
|
CGFloat newOffset = self.scrollView.contentOffset.x + [self swipeHorizontalInterval];
|
|
1190
|
-
NSLog(@"Swiped right to %f", newOffset);
|
|
1190
|
+
// NSLog(@"Swiped right to %f", newOffset);
|
|
1191
1191
|
[self scrollToHorizontalOffset:newOffset];
|
|
1192
1192
|
}
|
|
1193
1193
|
|
|
@@ -433,10 +433,8 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
|
|
433
433
|
|
|
434
434
|
if (mShouldLogContentAppeared) {
|
|
435
435
|
mShouldLogContentAppeared = false;
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
ReactMarker.logMarker(ReactMarkerConstants.CONTENT_APPEARED, mJSModuleName, mRootViewTag);
|
|
439
|
-
}
|
|
436
|
+
String jsModuleName = getJSModuleName();
|
|
437
|
+
ReactMarker.logMarker(ReactMarkerConstants.CONTENT_APPEARED, jsModuleName, mRootViewTag);
|
|
440
438
|
}
|
|
441
439
|
}
|
|
442
440
|
|
|
@@ -99,8 +99,11 @@ public class JavaTimerManager {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
// If the JS thread is busy for multiple frames we cancel any other pending runnable.
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
// We also capture the idleCallbackRunnable to tentatively fix:
|
|
103
|
+
// https://github.com/facebook/react-native/issues/44842
|
|
104
|
+
IdleCallbackRunnable idleCallbackRunnable = mCurrentIdleCallbackRunnable;
|
|
105
|
+
if (idleCallbackRunnable != null) {
|
|
106
|
+
idleCallbackRunnable.cancel();
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
mCurrentIdleCallbackRunnable = new IdleCallbackRunnable(frameTimeNanos);
|
|
@@ -63,6 +63,21 @@ public class ReactAndroidHWInputDeviceHelper {
|
|
|
63
63
|
.put(KeyEvent.KEYCODE_9, "9")
|
|
64
64
|
.put(KeyEvent.KEYCODE_CHANNEL_DOWN, "channelDown")
|
|
65
65
|
.put(KeyEvent.KEYCODE_CHANNEL_UP, "channelUp")
|
|
66
|
+
.put(KeyEvent.KEYCODE_BOOKMARK, "bookmark")
|
|
67
|
+
.put(KeyEvent.KEYCODE_AVR_INPUT, "avrInput")
|
|
68
|
+
.put(KeyEvent.KEYCODE_AVR_POWER, "avrPower")
|
|
69
|
+
.put(KeyEvent.KEYCODE_DVR, "dvr")
|
|
70
|
+
.put(KeyEvent.KEYCODE_GUIDE, "guide")
|
|
71
|
+
.put(KeyEvent.KEYCODE_PROG_RED, "red")
|
|
72
|
+
.put(KeyEvent.KEYCODE_PROG_GREEN, "green")
|
|
73
|
+
.put(KeyEvent.KEYCODE_PROG_BLUE, "blue")
|
|
74
|
+
.put(KeyEvent.KEYCODE_PROG_YELLOW, "yellow")
|
|
75
|
+
.put(KeyEvent.KEYCODE_STB_INPUT, "stbInput")
|
|
76
|
+
.put(KeyEvent.KEYCODE_STB_POWER, "stbPower")
|
|
77
|
+
.put(KeyEvent.KEYCODE_TV, "tv")
|
|
78
|
+
.put(KeyEvent.KEYCODE_TV_INPUT, "tvInput")
|
|
79
|
+
.put(KeyEvent.KEYCODE_WINDOW, "window")
|
|
80
|
+
.put(KeyEvent.KEYCODE_TV_TELETEXT, "teletext")
|
|
66
81
|
.build();
|
|
67
82
|
|
|
68
83
|
private static final Map<Integer, String> KEY_EVENTS_LONG_PRESS_ACTIONS =
|
|
@@ -75,6 +90,11 @@ public class ReactAndroidHWInputDeviceHelper {
|
|
|
75
90
|
.put(KeyEvent.KEYCODE_DPAD_RIGHT, "longRight")
|
|
76
91
|
.put(KeyEvent.KEYCODE_DPAD_DOWN, "longDown")
|
|
77
92
|
.put(KeyEvent.KEYCODE_DPAD_LEFT, "longLeft")
|
|
93
|
+
.put(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, "longPlayPause")
|
|
94
|
+
.put(KeyEvent.KEYCODE_MEDIA_REWIND, "longRewind")
|
|
95
|
+
.put(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD, "longFastForward")
|
|
96
|
+
.put(KeyEvent.KEYCODE_CHANNEL_DOWN, "longChannelDown")
|
|
97
|
+
.put(KeyEvent.KEYCODE_CHANNEL_UP, "longChannelUp")
|
|
78
98
|
.build();
|
|
79
99
|
|
|
80
100
|
/**
|
|
@@ -378,7 +378,9 @@ public class ReactHostImpl implements ReactHost {
|
|
|
378
378
|
public ReactSurface createSurface(
|
|
379
379
|
Context context, String moduleName, @Nullable Bundle initialProps) {
|
|
380
380
|
ReactSurfaceImpl surface = new ReactSurfaceImpl(context, moduleName, initialProps);
|
|
381
|
-
|
|
381
|
+
ReactSurfaceView surfaceView = new ReactSurfaceView(context, surface);
|
|
382
|
+
surfaceView.setShouldLogContentAppeared(true);
|
|
383
|
+
surface.attachView(surfaceView);
|
|
382
384
|
surface.attach(this);
|
|
383
385
|
return surface;
|
|
384
386
|
}
|
|
@@ -189,6 +189,11 @@ public class ReactSurfaceView extends ReactRootView {
|
|
|
189
189
|
return UIManagerType.FABRIC;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
@Override
|
|
193
|
+
public String getJSModuleName() {
|
|
194
|
+
return mSurface.getModuleName();
|
|
195
|
+
}
|
|
196
|
+
|
|
192
197
|
@Override
|
|
193
198
|
protected void dispatchJSTouchEvent(MotionEvent event) {
|
|
194
199
|
if (mJSTouchDispatcher == null) {
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
#include <atomic>
|
|
14
14
|
#include <condition_variable>
|
|
15
15
|
#include <cstdlib>
|
|
16
|
+
#include <deque>
|
|
16
17
|
#include <mutex>
|
|
17
|
-
#include <queue>
|
|
18
18
|
#include <sstream>
|
|
19
19
|
#include <thread>
|
|
20
20
|
|
|
@@ -51,6 +51,12 @@ class JSCRuntime : public jsi::Runtime {
|
|
|
51
51
|
const std::shared_ptr<const jsi::Buffer>& buffer,
|
|
52
52
|
const std::string& sourceURL) override;
|
|
53
53
|
|
|
54
|
+
// If we use this interface to implement microtasks in the host we need to
|
|
55
|
+
// polyfill `Promise` to use these methods, because JSC doesn't currently
|
|
56
|
+
// support providing a custom queue for its built-in implementation.
|
|
57
|
+
// Not doing this would result in a non-compliant behavior, as microtasks
|
|
58
|
+
// wouldn't execute in the order in which they were queued.
|
|
59
|
+
void queueMicrotask(const jsi::Function& callback) override;
|
|
54
60
|
bool drainMicrotasks(int maxMicrotasksHint = -1) override;
|
|
55
61
|
|
|
56
62
|
jsi::Object global() override;
|
|
@@ -265,6 +271,7 @@ class JSCRuntime : public jsi::Runtime {
|
|
|
265
271
|
std::atomic<bool> ctxInvalid_;
|
|
266
272
|
std::string desc_;
|
|
267
273
|
JSValueRef nativeStateSymbol_ = nullptr;
|
|
274
|
+
std::deque<jsi::Function> microtaskQueue_;
|
|
268
275
|
#ifndef NDEBUG
|
|
269
276
|
mutable std::atomic<intptr_t> objectCounter_;
|
|
270
277
|
mutable std::atomic<intptr_t> symbolCounter_;
|
|
@@ -385,6 +392,10 @@ JSCRuntime::JSCRuntime(JSGlobalContextRef ctx)
|
|
|
385
392
|
}
|
|
386
393
|
|
|
387
394
|
JSCRuntime::~JSCRuntime() {
|
|
395
|
+
// We need to clear the microtask queue to remove all references to the
|
|
396
|
+
// callbacks, so objectCounter_ would be 0 below.
|
|
397
|
+
microtaskQueue_.clear();
|
|
398
|
+
|
|
388
399
|
// On shutting down and cleaning up: when JSC is actually torn down,
|
|
389
400
|
// it calls JSC::Heap::lastChanceToFinalize internally which
|
|
390
401
|
// finalizes anything left over. But at this point,
|
|
@@ -441,7 +452,24 @@ jsi::Value JSCRuntime::evaluateJavaScript(
|
|
|
441
452
|
return createValue(res);
|
|
442
453
|
}
|
|
443
454
|
|
|
444
|
-
|
|
455
|
+
void JSCRuntime::queueMicrotask(const jsi::Function& callback) {
|
|
456
|
+
microtaskQueue_.emplace_back(
|
|
457
|
+
jsi::Value(*this, callback).asObject(*this).asFunction(*this));
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
bool JSCRuntime::drainMicrotasks(int /*maxMicrotasksHint*/) {
|
|
461
|
+
// Note that new jobs can be enqueued during the draining.
|
|
462
|
+
while (!microtaskQueue_.empty()) {
|
|
463
|
+
jsi::Function callback = std::move(microtaskQueue_.front());
|
|
464
|
+
|
|
465
|
+
// We need to pop before calling the callback because that might throw.
|
|
466
|
+
// When that happens, the host will call `drainMicrotasks` again to execute
|
|
467
|
+
// the remaining microtasks, and this one shouldn't run again.
|
|
468
|
+
microtaskQueue_.pop_front();
|
|
469
|
+
|
|
470
|
+
callback.call(*this);
|
|
471
|
+
}
|
|
472
|
+
|
|
445
473
|
return true;
|
|
446
474
|
}
|
|
447
475
|
|
|
@@ -126,6 +126,9 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation {
|
|
|
126
126
|
const std::shared_ptr<const PreparedJavaScript>& js) override {
|
|
127
127
|
return plain().evaluatePreparedJavaScript(js);
|
|
128
128
|
}
|
|
129
|
+
void queueMicrotask(const jsi::Function& callback) override {
|
|
130
|
+
return plain().queueMicrotask(callback);
|
|
131
|
+
}
|
|
129
132
|
bool drainMicrotasks(int maxMicrotasksHint) override {
|
|
130
133
|
return plain().drainMicrotasks(maxMicrotasksHint);
|
|
131
134
|
}
|
|
@@ -544,6 +547,10 @@ class WithRuntimeDecorator : public RuntimeDecorator<Plain, Base> {
|
|
|
544
547
|
Around around{with_};
|
|
545
548
|
return RD::evaluatePreparedJavaScript(js);
|
|
546
549
|
}
|
|
550
|
+
void queueMicrotask(const Function& callback) override {
|
|
551
|
+
Around around{with_};
|
|
552
|
+
RD::queueMicrotask(callback);
|
|
553
|
+
}
|
|
547
554
|
bool drainMicrotasks(int maxMicrotasksHint) override {
|
|
548
555
|
Around around{with_};
|
|
549
556
|
return RD::drainMicrotasks(maxMicrotasksHint);
|
|
@@ -209,6 +209,13 @@ class JSI_EXPORT Runtime {
|
|
|
209
209
|
virtual Value evaluatePreparedJavaScript(
|
|
210
210
|
const std::shared_ptr<const PreparedJavaScript>& js) = 0;
|
|
211
211
|
|
|
212
|
+
/// Queues a microtask in the JavaScript VM internal Microtask (a.k.a. Job in
|
|
213
|
+
/// ECMA262) queue, to be executed when the host drains microtasks in
|
|
214
|
+
/// its event loop implementation.
|
|
215
|
+
///
|
|
216
|
+
/// \param callback a function to be executed as a microtask.
|
|
217
|
+
virtual void queueMicrotask(const jsi::Function& callback) = 0;
|
|
218
|
+
|
|
212
219
|
/// Drain the JavaScript VM internal Microtask (a.k.a. Job in ECMA262) queue.
|
|
213
220
|
///
|
|
214
221
|
/// \param maxMicrotasksHint a hint to tell an implementation that it should
|
package/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp
CHANGED
|
@@ -86,6 +86,38 @@ struct JNIArgs {
|
|
|
86
86
|
std::vector<jobject> globalRefs_;
|
|
87
87
|
};
|
|
88
88
|
|
|
89
|
+
jsi::Value createJSRuntimeError(
|
|
90
|
+
jsi::Runtime& runtime,
|
|
91
|
+
const std::string& message) {
|
|
92
|
+
return runtime.global()
|
|
93
|
+
.getPropertyAsFunction(runtime, "Error")
|
|
94
|
+
.call(runtime, message);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
jsi::Value createRejectionError(jsi::Runtime& rt, const folly::dynamic& args) {
|
|
98
|
+
react_native_assert(
|
|
99
|
+
args.size() == 1 && "promise reject should has only one argument");
|
|
100
|
+
|
|
101
|
+
auto value = jsi::valueFromDynamic(rt, args[0]);
|
|
102
|
+
react_native_assert(value.isObject() && "promise reject should return a map");
|
|
103
|
+
|
|
104
|
+
const jsi::Object& valueAsObject = value.asObject(rt);
|
|
105
|
+
|
|
106
|
+
auto messageProperty = valueAsObject.getProperty(rt, "message");
|
|
107
|
+
auto jsError =
|
|
108
|
+
createJSRuntimeError(rt, messageProperty.asString(rt).utf8(rt));
|
|
109
|
+
|
|
110
|
+
auto jsErrorAsObject = jsError.asObject(rt);
|
|
111
|
+
auto propertyNames = valueAsObject.getPropertyNames(rt);
|
|
112
|
+
for (size_t i = 0; i < propertyNames.size(rt); ++i) {
|
|
113
|
+
auto propertyName = jsi::PropNameID::forString(
|
|
114
|
+
rt, propertyNames.getValueAtIndex(rt, i).asString(rt));
|
|
115
|
+
jsErrorAsObject.setProperty(
|
|
116
|
+
rt, propertyName, valueAsObject.getProperty(rt, propertyName));
|
|
117
|
+
}
|
|
118
|
+
return jsError;
|
|
119
|
+
}
|
|
120
|
+
|
|
89
121
|
auto createJavaCallback(
|
|
90
122
|
jsi::Runtime& rt,
|
|
91
123
|
jsi::Function&& function,
|
|
@@ -98,7 +130,6 @@ auto createJavaCallback(
|
|
|
98
130
|
LOG(FATAL) << "Callback arg cannot be called more than once";
|
|
99
131
|
return;
|
|
100
132
|
}
|
|
101
|
-
|
|
102
133
|
callback->call([args = std::move(args)](
|
|
103
134
|
jsi::Runtime& rt, jsi::Function& jsFunction) {
|
|
104
135
|
std::vector<jsi::Value> jsArgs;
|
|
@@ -112,6 +143,26 @@ auto createJavaCallback(
|
|
|
112
143
|
});
|
|
113
144
|
}
|
|
114
145
|
|
|
146
|
+
auto createJavaRejectCallback(
|
|
147
|
+
jsi::Runtime& rt,
|
|
148
|
+
jsi::Function&& function,
|
|
149
|
+
std::shared_ptr<CallInvoker> jsInvoker) {
|
|
150
|
+
std::optional<AsyncCallback<>> callback(
|
|
151
|
+
{rt, std::move(function), std::move(jsInvoker)});
|
|
152
|
+
return JCxxCallbackImpl::newObjectCxxArgs(
|
|
153
|
+
[callback = std::move(callback)](folly::dynamic args) mutable {
|
|
154
|
+
if (!callback) {
|
|
155
|
+
LOG(FATAL) << "Callback arg cannot be called more than once";
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
callback->call([args = std::move(args)](
|
|
159
|
+
jsi::Runtime& rt, jsi::Function& jsFunction) {
|
|
160
|
+
jsFunction.call(rt, createRejectionError(rt, args));
|
|
161
|
+
});
|
|
162
|
+
callback = std::nullopt;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
115
166
|
struct JPromiseImpl : public jni::JavaClass<JPromiseImpl> {
|
|
116
167
|
constexpr static auto kJavaDescriptor =
|
|
117
168
|
"Lcom/facebook/react/bridge/PromiseImpl;";
|
|
@@ -407,14 +458,6 @@ jsi::Value convertFromJMapToValue(JNIEnv* env, jsi::Runtime& rt, jobject arg) {
|
|
|
407
458
|
return jsi::valueFromDynamic(rt, result->cthis()->consume());
|
|
408
459
|
}
|
|
409
460
|
|
|
410
|
-
jsi::Value createJSRuntimeError(
|
|
411
|
-
jsi::Runtime& runtime,
|
|
412
|
-
const std::string& message) {
|
|
413
|
-
return runtime.global()
|
|
414
|
-
.getPropertyAsFunction(runtime, "Error")
|
|
415
|
-
.call(runtime, message);
|
|
416
|
-
}
|
|
417
|
-
|
|
418
461
|
/**
|
|
419
462
|
* Creates JSError with current JS runtime stack and Throwable stack trace.
|
|
420
463
|
*/
|
|
@@ -855,7 +898,7 @@ jsi::Value JavaTurboModule::invokeJavaMethod(
|
|
|
855
898
|
runtime,
|
|
856
899
|
args[0].getObject(runtime).getFunction(runtime),
|
|
857
900
|
jsInvoker_);
|
|
858
|
-
auto reject =
|
|
901
|
+
auto reject = createJavaRejectCallback(
|
|
859
902
|
runtime,
|
|
860
903
|
args[1].getObject(runtime).getFunction(runtime),
|
|
861
904
|
jsInvoker_);
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
#include "RuntimeScheduler_Legacy.h"
|
|
9
9
|
#include "SchedulerPriorityUtils.h"
|
|
10
10
|
|
|
11
|
+
#include <cxxreact/ErrorUtils.h>
|
|
11
12
|
#include <react/renderer/debug/SystraceSection.h>
|
|
12
13
|
#include <utility>
|
|
13
|
-
#include "ErrorUtils.h"
|
|
14
14
|
|
|
15
15
|
namespace facebook::react {
|
|
16
16
|
|
|
@@ -136,7 +136,7 @@ void RuntimeScheduler_Legacy::callExpiredTasks(jsi::Runtime& runtime) {
|
|
|
136
136
|
executeTask(runtime, topPriorityTask, didUserCallbackTimeout);
|
|
137
137
|
}
|
|
138
138
|
} catch (jsi::JSError& error) {
|
|
139
|
-
|
|
139
|
+
handleJSError(runtime, error, true);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
currentPriority_ = previousPriority;
|
|
@@ -182,7 +182,7 @@ void RuntimeScheduler_Legacy::startWorkLoop(jsi::Runtime& runtime) {
|
|
|
182
182
|
executeTask(runtime, topPriorityTask, didUserCallbackTimeout);
|
|
183
183
|
}
|
|
184
184
|
} catch (jsi::JSError& error) {
|
|
185
|
-
|
|
185
|
+
handleJSError(runtime, error, true);
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
currentPriority_ = previousPriority;
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
#include <react/featureflags/ReactNativeFeatureFlags.h>
|
|
13
13
|
#include <react/renderer/debug/SystraceSection.h>
|
|
14
14
|
#include <utility>
|
|
15
|
-
#include "ErrorUtils.h"
|
|
16
15
|
|
|
17
16
|
namespace facebook::react {
|
|
18
17
|
|
|
@@ -104,7 +103,7 @@ bool RuntimeScheduler_Modern::getShouldYield() const noexcept {
|
|
|
104
103
|
std::shared_lock lock(schedulingMutex_);
|
|
105
104
|
|
|
106
105
|
return syncTaskRequests_ > 0 ||
|
|
107
|
-
(!taskQueue_.empty() && taskQueue_.top() != currentTask_);
|
|
106
|
+
(!taskQueue_.empty() && taskQueue_.top().get() != currentTask_);
|
|
108
107
|
}
|
|
109
108
|
|
|
110
109
|
bool RuntimeScheduler_Modern::getIsSynchronous() const noexcept {
|
|
@@ -144,9 +143,8 @@ void RuntimeScheduler_Modern::executeNowOnTheSameThread(
|
|
|
144
143
|
auto priority = SchedulerPriority::ImmediatePriority;
|
|
145
144
|
auto expirationTime =
|
|
146
145
|
currentTime + timeoutForSchedulerPriority(priority);
|
|
147
|
-
auto task = std::make_shared<Task>(
|
|
148
|
-
priority, std::move(callback), expirationTime);
|
|
149
146
|
|
|
147
|
+
auto task = Task{priority, std::move(callback), expirationTime};
|
|
150
148
|
executeTask(runtime, task, currentTime);
|
|
151
149
|
|
|
152
150
|
isSynchronous_ = false;
|
|
@@ -231,21 +229,17 @@ void RuntimeScheduler_Modern::startWorkLoop(
|
|
|
231
229
|
|
|
232
230
|
auto previousPriority = currentPriority_;
|
|
233
231
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
auto topPriorityTask = selectTask(currentTime, onlyExpired);
|
|
232
|
+
while (syncTaskRequests_ == 0) {
|
|
233
|
+
auto currentTime = now_();
|
|
234
|
+
auto topPriorityTask = selectTask(currentTime, onlyExpired);
|
|
238
235
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
executeTask(runtime, topPriorityTask, currentTime);
|
|
236
|
+
if (!topPriorityTask) {
|
|
237
|
+
// No pending work to do.
|
|
238
|
+
// Events will restart the loop when necessary.
|
|
239
|
+
break;
|
|
246
240
|
}
|
|
247
|
-
|
|
248
|
-
|
|
241
|
+
|
|
242
|
+
executeTask(runtime, *topPriorityTask, currentTime);
|
|
249
243
|
}
|
|
250
244
|
|
|
251
245
|
currentPriority_ = previousPriority;
|
|
@@ -280,19 +274,19 @@ std::shared_ptr<Task> RuntimeScheduler_Modern::selectTask(
|
|
|
280
274
|
|
|
281
275
|
void RuntimeScheduler_Modern::executeTask(
|
|
282
276
|
jsi::Runtime& runtime,
|
|
283
|
-
|
|
277
|
+
Task& task,
|
|
284
278
|
RuntimeSchedulerTimePoint currentTime) {
|
|
285
|
-
auto didUserCallbackTimeout = task
|
|
279
|
+
auto didUserCallbackTimeout = task.expirationTime <= currentTime;
|
|
286
280
|
|
|
287
281
|
SystraceSection s(
|
|
288
282
|
"RuntimeScheduler::executeTask",
|
|
289
283
|
"priority",
|
|
290
|
-
serialize(task
|
|
284
|
+
serialize(task.priority),
|
|
291
285
|
"didUserCallbackTimeout",
|
|
292
286
|
didUserCallbackTimeout);
|
|
293
287
|
|
|
294
|
-
currentTask_ = task;
|
|
295
|
-
currentPriority_ = task
|
|
288
|
+
currentTask_ = &task;
|
|
289
|
+
currentPriority_ = task.priority;
|
|
296
290
|
|
|
297
291
|
executeMacrotask(runtime, task, didUserCallbackTimeout);
|
|
298
292
|
|
|
@@ -305,6 +299,8 @@ void RuntimeScheduler_Modern::executeTask(
|
|
|
305
299
|
// "Update the rendering" step.
|
|
306
300
|
updateRendering();
|
|
307
301
|
}
|
|
302
|
+
|
|
303
|
+
currentTask_ = nullptr;
|
|
308
304
|
}
|
|
309
305
|
|
|
310
306
|
/**
|
|
@@ -326,16 +322,20 @@ void RuntimeScheduler_Modern::updateRendering() {
|
|
|
326
322
|
|
|
327
323
|
void RuntimeScheduler_Modern::executeMacrotask(
|
|
328
324
|
jsi::Runtime& runtime,
|
|
329
|
-
|
|
325
|
+
Task& task,
|
|
330
326
|
bool didUserCallbackTimeout) const {
|
|
331
327
|
SystraceSection s("RuntimeScheduler::executeMacrotask");
|
|
332
328
|
|
|
333
|
-
|
|
329
|
+
try {
|
|
330
|
+
auto result = task.execute(runtime, didUserCallbackTimeout);
|
|
334
331
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
332
|
+
if (result.isObject() && result.getObject(runtime).isFunction(runtime)) {
|
|
333
|
+
// If the task returned a continuation callback, we re-assign it to the
|
|
334
|
+
// task and keep the task in the queue.
|
|
335
|
+
task.callback = result.getObject(runtime).getFunction(runtime);
|
|
336
|
+
}
|
|
337
|
+
} catch (jsi::JSError& error) {
|
|
338
|
+
handleJSError(runtime, error, true);
|
|
339
339
|
}
|
|
340
340
|
}
|
|
341
341
|
|
|
@@ -139,7 +139,7 @@ class RuntimeScheduler_Modern final : public RuntimeSchedulerBase {
|
|
|
139
139
|
TaskPriorityComparer>
|
|
140
140
|
taskQueue_;
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
Task* currentTask_{};
|
|
143
143
|
|
|
144
144
|
/**
|
|
145
145
|
* This protects the access to `taskQueue_` and `isWorkLoopScheduled_`.
|
|
@@ -168,12 +168,12 @@ class RuntimeScheduler_Modern final : public RuntimeSchedulerBase {
|
|
|
168
168
|
*/
|
|
169
169
|
void executeTask(
|
|
170
170
|
jsi::Runtime& runtime,
|
|
171
|
-
|
|
171
|
+
Task& task,
|
|
172
172
|
RuntimeSchedulerTimePoint currentTime);
|
|
173
173
|
|
|
174
174
|
void executeMacrotask(
|
|
175
175
|
jsi::Runtime& runtime,
|
|
176
|
-
|
|
176
|
+
Task& task,
|
|
177
177
|
bool didUserCallbackTimeout) const;
|
|
178
178
|
|
|
179
179
|
void updateRendering();
|
|
@@ -32,20 +32,22 @@ jsi::Value Task::execute(jsi::Runtime& runtime, bool didUserCallbackTimeout) {
|
|
|
32
32
|
return result;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
// We get the value of the callback and reset it immediately to avoid it being
|
|
36
|
+
// called more than once (including when the callback throws).
|
|
37
|
+
auto originalCallback = std::move(*callback);
|
|
38
|
+
callback.reset();
|
|
36
39
|
|
|
37
|
-
if (
|
|
40
|
+
if (originalCallback.index() == 0) {
|
|
38
41
|
// Callback in JavaScript is expecting a single bool parameter.
|
|
39
42
|
// React team plans to remove it in the future when a scheduler bug on web
|
|
40
43
|
// is resolved.
|
|
41
|
-
result =
|
|
42
|
-
|
|
44
|
+
result = std::get<jsi::Function>(originalCallback)
|
|
45
|
+
.call(runtime, {didUserCallbackTimeout});
|
|
43
46
|
} else {
|
|
44
47
|
// Calling a raw callback
|
|
45
|
-
std::get<RawCallback>(
|
|
48
|
+
std::get<RawCallback>(originalCallback)(runtime);
|
|
46
49
|
}
|
|
47
|
-
|
|
48
|
-
callback.reset();
|
|
50
|
+
|
|
49
51
|
return result;
|
|
50
52
|
}
|
|
51
53
|
|
|
@@ -1021,6 +1021,52 @@ TEST_P(RuntimeSchedulerTest, modernTwoThreadsRequestAccessToTheRuntime) {
|
|
|
1021
1021
|
EXPECT_EQ(stubQueue_->size(), 0);
|
|
1022
1022
|
}
|
|
1023
1023
|
|
|
1024
|
+
TEST_P(RuntimeSchedulerTest, errorInTaskShouldNotStopMicrotasks) {
|
|
1025
|
+
// Only for modern runtime scheduler
|
|
1026
|
+
if (!GetParam()) {
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
auto microtaskRan = false;
|
|
1031
|
+
auto taskRan = false;
|
|
1032
|
+
|
|
1033
|
+
auto callback = createHostFunctionFromLambda([&](bool /* unused */) {
|
|
1034
|
+
taskRan = true;
|
|
1035
|
+
|
|
1036
|
+
auto microtaskCallback = jsi::Function::createFromHostFunction(
|
|
1037
|
+
*runtime_,
|
|
1038
|
+
jsi::PropNameID::forUtf8(*runtime_, "microtask1"),
|
|
1039
|
+
3,
|
|
1040
|
+
[&](jsi::Runtime& /*unused*/,
|
|
1041
|
+
const jsi::Value& /*unused*/,
|
|
1042
|
+
const jsi::Value* /*arguments*/,
|
|
1043
|
+
size_t /*unused*/) -> jsi::Value {
|
|
1044
|
+
microtaskRan = true;
|
|
1045
|
+
return jsi::Value::undefined();
|
|
1046
|
+
});
|
|
1047
|
+
|
|
1048
|
+
runtime_->queueMicrotask(microtaskCallback);
|
|
1049
|
+
|
|
1050
|
+
throw jsi::JSError(*runtime_, "Test error");
|
|
1051
|
+
|
|
1052
|
+
return jsi::Value::undefined();
|
|
1053
|
+
});
|
|
1054
|
+
|
|
1055
|
+
runtimeScheduler_->scheduleTask(
|
|
1056
|
+
SchedulerPriority::NormalPriority, std::move(callback));
|
|
1057
|
+
|
|
1058
|
+
EXPECT_EQ(taskRan, false);
|
|
1059
|
+
EXPECT_EQ(microtaskRan, false);
|
|
1060
|
+
EXPECT_EQ(stubQueue_->size(), 1);
|
|
1061
|
+
|
|
1062
|
+
stubQueue_->tick();
|
|
1063
|
+
|
|
1064
|
+
EXPECT_EQ(taskRan, 1);
|
|
1065
|
+
EXPECT_EQ(microtaskRan, 1);
|
|
1066
|
+
EXPECT_EQ(stubQueue_->size(), 0);
|
|
1067
|
+
EXPECT_EQ(stubErrorUtils_->getReportFatalCallCount(), 1);
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1024
1070
|
INSTANTIATE_TEST_SUITE_P(
|
|
1025
1071
|
UseModernRuntimeScheduler,
|
|
1026
1072
|
RuntimeSchedulerTest,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-tvos",
|
|
3
|
-
"version": "0.74.
|
|
3
|
+
"version": "0.74.3-0",
|
|
4
4
|
"description": "A framework for building native apps using React",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -108,16 +108,16 @@
|
|
|
108
108
|
},
|
|
109
109
|
"dependencies": {
|
|
110
110
|
"@jest/create-cache-key-function": "^29.6.3",
|
|
111
|
-
"@react-native-community/cli": "13.6.
|
|
112
|
-
"@react-native-community/cli-platform-android": "13.6.
|
|
113
|
-
"@react-native-community/cli-platform-ios": "13.6.
|
|
114
|
-
"@react-native/assets-registry": "0.74.
|
|
115
|
-
"@react-native/codegen": "0.74.
|
|
116
|
-
"@react-native/community-cli-plugin": "0.74.
|
|
117
|
-
"@react-native/gradle-plugin": "0.74.
|
|
118
|
-
"@react-native/js-polyfills": "0.74.
|
|
119
|
-
"@react-native/normalize-colors": "0.74.
|
|
120
|
-
"@react-native-tvos/virtualized-lists": "0.74.
|
|
111
|
+
"@react-native-community/cli": "13.6.9",
|
|
112
|
+
"@react-native-community/cli-platform-android": "13.6.9",
|
|
113
|
+
"@react-native-community/cli-platform-ios": "13.6.9",
|
|
114
|
+
"@react-native/assets-registry": "0.74.85",
|
|
115
|
+
"@react-native/codegen": "0.74.85",
|
|
116
|
+
"@react-native/community-cli-plugin": "0.74.85",
|
|
117
|
+
"@react-native/gradle-plugin": "0.74.85",
|
|
118
|
+
"@react-native/js-polyfills": "0.74.85",
|
|
119
|
+
"@react-native/normalize-colors": "0.74.85",
|
|
120
|
+
"@react-native-tvos/virtualized-lists": "0.74.3-0",
|
|
121
121
|
"abort-controller": "^3.0.0",
|
|
122
122
|
"anser": "^1.4.9",
|
|
123
123
|
"ansi-regex": "^5.0.0",
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
"scheduler": "0.24.0-canary-efb381bbf-20230505",
|
|
143
143
|
"stacktrace-parser": "^0.1.10",
|
|
144
144
|
"whatwg-fetch": "^3.0.0",
|
|
145
|
-
"ws": "^6.2.
|
|
145
|
+
"ws": "^6.2.3",
|
|
146
146
|
"yargs": "^17.6.2"
|
|
147
147
|
},
|
|
148
148
|
"codegenConfig": {
|
|
@@ -164,6 +164,6 @@
|
|
|
164
164
|
]
|
|
165
165
|
},
|
|
166
166
|
"devDependencies": {
|
|
167
|
-
"react-native-core": "npm:react-native@0.74.
|
|
167
|
+
"react-native-core": "npm:react-native@0.74.3"
|
|
168
168
|
}
|
|
169
169
|
}
|
|
@@ -365,7 +365,7 @@ function computeOutputPath(projectRoot, baseOutputPath, pkgJson, platform) {
|
|
|
365
365
|
if (baseOutputPath == null) {
|
|
366
366
|
const outputDirFromPkgJson = readOutputDirFromPkgJson(pkgJson, platform);
|
|
367
367
|
if (outputDirFromPkgJson != null) {
|
|
368
|
-
baseOutputPath = outputDirFromPkgJson;
|
|
368
|
+
baseOutputPath = path.join(projectRoot, outputDirFromPkgJson);
|
|
369
369
|
} else {
|
|
370
370
|
baseOutputPath = projectRoot;
|
|
371
371
|
}
|
package/sdks/.hermesversion
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
hermes-2024-06-
|
|
1
|
+
hermes-2024-06-28-RNv0.74.3-8a42e289991d48575dcb4012ea9205d707dac43d
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/template/package.json
CHANGED
|
@@ -11,18 +11,18 @@
|
|
|
11
11
|
"test": "jest"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"expo": "^
|
|
14
|
+
"expo": "^51.0.17",
|
|
15
15
|
"react": "18.2.0",
|
|
16
|
-
"react-native": "npm:react-native-tvos@0.74.
|
|
16
|
+
"react-native": "npm:react-native-tvos@0.74.3-0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@babel/core": "^7.20.0",
|
|
20
20
|
"@babel/preset-env": "^7.20.0",
|
|
21
21
|
"@babel/runtime": "^7.20.0",
|
|
22
|
-
"@react-native/babel-preset": "0.74.
|
|
23
|
-
"@react-native/eslint-config": "0.74.
|
|
24
|
-
"@react-native/metro-config": "0.74.
|
|
25
|
-
"@react-native/typescript-config": "0.74.
|
|
22
|
+
"@react-native/babel-preset": "0.74.85",
|
|
23
|
+
"@react-native/eslint-config": "0.74.85",
|
|
24
|
+
"@react-native/metro-config": "0.74.85",
|
|
25
|
+
"@react-native/typescript-config": "0.74.85",
|
|
26
26
|
"@types/react": "^18.2.6",
|
|
27
27
|
"@types/react-test-renderer": "^18.0.0",
|
|
28
28
|
"babel-jest": "^29.6.3",
|
|
@@ -1,34 +0,0 @@
|
|
|
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
|
-
#include <jsi/jsi.h>
|
|
9
|
-
|
|
10
|
-
namespace facebook::react {
|
|
11
|
-
|
|
12
|
-
inline static void handleFatalError(
|
|
13
|
-
jsi::Runtime& runtime,
|
|
14
|
-
const jsi::JSError& error) {
|
|
15
|
-
auto reportFatalError = "reportFatalError";
|
|
16
|
-
auto errorUtils = runtime.global().getProperty(runtime, "ErrorUtils");
|
|
17
|
-
if (errorUtils.isUndefined() || !errorUtils.isObject() ||
|
|
18
|
-
!errorUtils.getObject(runtime).hasProperty(runtime, reportFatalError)) {
|
|
19
|
-
// ErrorUtils was not set up. This probably means the bundle didn't
|
|
20
|
-
// load properly.
|
|
21
|
-
throw jsi::JSError(
|
|
22
|
-
runtime,
|
|
23
|
-
"ErrorUtils is not set up properly. Something probably went wrong trying to load the JS bundle. Trying to report error " +
|
|
24
|
-
error.getMessage(),
|
|
25
|
-
error.getStack());
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
auto func = errorUtils.asObject(runtime).getPropertyAsFunction(
|
|
29
|
-
runtime, reportFatalError);
|
|
30
|
-
|
|
31
|
-
func.call(runtime, error.value());
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
} // namespace facebook::react
|