Summary:
This diff exposes a new API in FabricUIManager called getInspectorDataForInstance. The goal of this method is to return React metadata for a Native view.
This data will be used from partner teams to build tools that uses React metadata in RN
Data returned from React: P429701924
changelog: [internal] internal
allow-large-files
Reviewed By: JoshuaGross
Differential Revision: D29747864
fbshipit-source-id: 8cb55573be08cb530f7e3c83eed8b4fcf43e7781
Summary:
I'm hunting down the source of a perf regression on a screen and think that having these systrace sections could be handy for this and future investigations.
Changelog: [internal]
Reviewed By: mdvacca
Differential Revision: D29802969
fbshipit-source-id: f4030261da8888ddeb32ae41b9cf2b25af6a5583
Summary:
In the refactor in D28933824 (https://github.com/facebook/react-native/commit/6b601db8b83337415113a123d780fb64aa67af42), an early return was accidentally deleted. This causes incorrect measurements to be returned, which can break a few things including Text Inline Views.
Changelog: [internal]
Reviewed By: mdvacca
Differential Revision: D29122235
fbshipit-source-id: 76c8991132e22cd4e0fc1c277447c4dba751adfb
Summary:
Changelog: [internal]
Add an option to make all measure calls asynchronous.
Reviewed By: JoshuaGross
Differential Revision: D28934444
fbshipit-source-id: 57a320b03add0182b4646b13ed4b692b899ddea3
Summary:
Changelog: [internal]
Move call of getRelativeLayoutMetrics to lambda.
The reason for this is so we can make all of "measure" calls asynchronous.
Reviewed By: JoshuaGross
Differential Revision: D28933824
fbshipit-source-id: f77fc1d06d5cd4706d52a02253a3e754e8e8fa44
Summary:
Changelog: [internal]
Use getter function instead of accessing ivar. This makes for clearer APIs.
React part is implemented in https://github.com/facebook/react/pull/21553
Reviewed By: JoshuaGross
Differential Revision: D28675372
fbshipit-source-id: cf99f8482067bfc0fd57d39fda9656abd665bb69
Summary:
This diff extends startSurface and setSurfaceProps methods with the new parameter called displayMode
changelog: [internal] internal
Reviewed By: yungsters
Differential Revision: D27669847
fbshipit-source-id: c2ddb690ca897e46e00f07b491b91bb2bc8e847d
Summary:
This diff introduces a new fabric API called setSurfaceProps that will be used to call the new JS api "setSurfaceProps"
changelog: [internal] internal
Reviewed By: sammy-SC
Differential Revision: D27607588
fbshipit-source-id: 36a19f728af244d7e72687d9305b1c568e2b8ec6
Summary:
Changelog: [internal]
Add support for a return value when calling JavaScript functions in UIManagerBinding.
Reviewed By: mdvacca
Differential Revision: D27470817
fbshipit-source-id: 38de92dd913af61d879f1cc5962d417f51da73b0
Summary:
The non-Fabric API has a `blockNativeResponder` param in setJSResponder. Make sure to pass that along in Fabric.
On Android this allows us to respect the flag and do the same thing non-Fabric was doing if `blockNativeResponder` is false. It's not clear yet what the impact is on iOS.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D27058806
fbshipit-source-id: aa5074fa46191d78f5292a93d9040ab4bb58ca66
Summary:
Right now there are places in UIManagerBinding.cpp where native java exceptions will be thrown if calling JSI functions results in errors, such as:
```Trying to report error getPropertyAsObject: property '__fbBatchedBridge' is undefined, expected an Object
Error: getPropertyAsObject: property '__fbBatchedBridge' is undefined, expected an Object
```
https://www.internalfb.com/intern/logview/details/facebook_android_javascripterrors/358181062b47b9561e60427bbb3816a9
In this diff I added LOG(ERROR) and checks because:
1, Throwing errors neither prevents the JSI errors nor handles them properly, checks prevent JSI errors from happening.
2, Errors are aggregated in Logview with other JSI errors as "Error: android_crash:com.facebook.react.devsupport.JSException:facebook::jni::throwNewJavaException" which keeps the SLA task open forever, checks can prevent JSI errors so they won't lead to exceptions, and LOG(ERROR) will make sure we have enough info for debugging.
Changelog:
[General][Changed] - Add checks and logs to for better error handling
Reviewed By: JoshuaGross
Differential Revision: D26885562
fbshipit-source-id: c0c1c057342e9efc0ff708188703f4332036e7a9
Summary:
Changelog: [internal]
UIManager shouldn't be retained in lambda because if it outlives runtime it causes a crash.
UIManager -> ComponentDescriptorRegistry -> ParagraphComponentDescriptor -> TextLayoutManager's cache -> AttributedString::Fragment -> ShaviewView -> EventEmitter -> EventTarget -> Pointer
This is the chain of ownership that can cause a crash if UIManager is retained for longer than JS runtime.
{F459238235}
Reviewed By: JoshuaGross
Differential Revision: D26851194
fbshipit-source-id: 644cdee34ba9286618659d847fb2e78bc301d049
Summary:
Changelog: [internal]
Check for null before passing it to `EventTarget` constructor.
Reviewed By: JoshuaGross
Differential Revision: D26605779
fbshipit-source-id: a2773c8123d83c25736bccefe656d1def8794091
Summary:
Changelog: [internal]
`shadowNodeFromValue` can return nullptr. Let's make sure it returns valid value before dispatching command.
Reviewed By: JoshuaGross
Differential Revision: D26605350
fbshipit-source-id: eb9a0347c95ba07fd7e9b7ddeca7e6d6011f50ad
Summary:
Changelog: [internal]
### Why does the crash happen?
The crash can happen if runtime is destroyed before background executor lambda is run. Destroying a shadow node after runtime leads to a crash through the chain of ownerships.
Chain of ownership:
`ShadowNode -> ShadowNodeFamily -> EventEmitter -> EventTarget -> Pointer`
Pointer tries to call `invalidate` method on raw pointer to the runtime which is gone.
https://www.internalfb.com/intern/diffusion/FBS/browse/master/xplat/js/react-native-github/ReactCommon/jsi/jsi/jsi.h?commit=2ee3ae0c6a64&lines=335-339
To work around this, weak pointers are passed to lambda. This way the lambda is less likely to be the last owner of shadow nodes. Possibility of race still exists but it less likely to happen.
## Other solution
Alternatively, we could make sure native Runnable queue in Java is emptied as part of tear down process. We can even implement both solutions as they are semantically correct.
Reviewed By: shergin
Differential Revision: D26582554
fbshipit-source-id: b1b8a92237902bc4c40376176f575caa24a41a05
Summary:
See react_native_assert.{h,cpp}. Because of the BUCK+Android issue where NDEBUG is always defined, we use react_native_assert instead of assert to enable xplat asserts in debug/dev mode.
This migrates most of the codebase, but probably not 100%. The goal is to increase assertion coverage on Android, not to get to 100% (yet).
Changelog: [Internal]
Reviewed By: RSNara
Differential Revision: D26562866
fbshipit-source-id: a7bf2055b973e1d3650ed8d68a6d02d556604af9
Summary:
This is a Fabric-compliant implementation of `JSResponder` feature. To make it work e2e we also need to update FabricRenderer in React repository. But before we can do this, we need to ship the native changes.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D24630027
fbshipit-source-id: 70c30e1250b554d83862956b536714704093072f
Summary:
Changelog: [internal]
Name `shouldCancel` is misleading. It implies the commit is cancelled and doesn't happen.
`shouldYield` expresses the intent better, because the commit's changes do eventually reach mounting layer but the current commit is rather yielding to the next one.
Reviewed By: mdvacca
Differential Revision: D26126121
fbshipit-source-id: 18988f217cbc651f0010f6e2381682bdbaed8bd4
Summary:
Changelog: [internal]
In theory, a commit from different surface could cancel a commit for unrelated surface. Adding surfaceId to cancellation logic assures this doesn't happen.
Reviewed By: shergin
Differential Revision: D26126003
fbshipit-source-id: 15b9b73f1000a2b4ae882e0a5129fe26fbb53fd2
Summary:
Changelog: [internal]
This simplifies logic, there is no need to keep the counter as an ivar of UIManager.
Reviewed By: JoshuaGross, shergin
Differential Revision: D26125928
fbshipit-source-id: bd266586463a9f9b85d6dc189cdab19f79e3d107
Summary:
This changes how we access UIManagerBinding in Fabric code. Instead of storing a pointer to it and accessing it, now we just request it from JavaScript runtime on demand. After a week of testing, I hope we will be able to simplify retaining and referencing logic between UIManager and UIManagerBinding. The change is gated just in case to have the ability to turn this new implementation off.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D26082788
fbshipit-source-id: 211c551fe1aaba9b0bff18478e40e1e1f32e999c
Summary:
This is a small simplification of the logic we have in UIManagerBinding choosing the way to call `completeRoot`. It removes an additional check for for `sharedUIManager->backgroundExecutor_` not being empty. We don't need it because it never changes and we already have the same check several lines above.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D25953674
fbshipit-source-id: 683b3e51a792160d480551a65c40492ce28938e4
Summary:
This is the core (Cxx) Fabric implementation of sendAccessibilityEvent. No platform support is added in this diff (Android and iOS do not build yet).
See following diffs.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D25852412
fbshipit-source-id: 88b7d8e2e251183dfe7fb377a4cffbac8f458656
Summary:
Changelog: [internal]
Previous implementation of "measure" in UIManagerBinding returned 0, 0 for x and y coordinates.
Reviewed By: shergin
Differential Revision: D25681586
fbshipit-source-id: fa69b6d4803f083a8299e00cae8bb59932c8bf78
Summary:
This fix is still a little hypothetical. We have a few different JS errors that we're seeing with bridgeless mode that seem to be caused by Fabric trying to access `__fbBatchedBridge` from C++. I think what's happening is:
1. User encounters an unrelated JS error very early in rendering a new surface (possibly while the bundle is still loading?)
2. In release builds, BridgelessReactFragment handles the error by stopping the surface and rendering a retry button (actually, the surface is stopped in a bunch of places in BaseFbReactFragment, which might be why this is popping up now - I recently refactored that class to share more of its logic in bridgeless mode)
3. Fabric stops the surface by first checking to see if the custom binding `RN$stopSurface` exists; if not, it falls back to calling the registered callable module `ReactFabric`.
I think #3 is where things are going wrong for bridgeless mode; if you call stopSurface before `RN$stopSurface` is installed (which happens when ReactFabric shim is required) then you'll fall back to the bridge version.
My solution here is to instead rely on a flag set in C++ to determine whether we're in bridgeless mode, and then check to see if the stopSurface binding has been installed. If not, we just noop - if the ReactFabric shim hasn't been required, we probably don't actually have a React surface that needs to be stopped.
At least, that's my current theory. We'll see if this actually works.
Changelog: [Fixed][iOS] Fix an issue calling stopSurface in bridgeless mode before surface is started
Reviewed By: mdvacca
Differential Revision: D25453696
fbshipit-source-id: bff76675c43989101d0ba5ae0aba60089db230bf
Summary:
Changelog: [internal]
Background executor performs unnecessary operations when second `completeRoot` message from React arrives before first `completeRoot` was finished. This produces unnecessary `ShadowViewMutations`.
Mechanism:
Everytime `completeRoot` is received, before the call is dispatched on the background queue, `completeRootEventCounter_DO_NOT_USE_` is incremented.
Inside `ShadowTree::tryCommit` we check if the value has been incremented to determine if another `completeRoot` is queued.
Reviewed By: JoshuaGross
Differential Revision: D24419160
fbshipit-source-id: 11e19026feca01db6c8981b093a691a6b58a006f
Summary:
Changelog: [internal]
Fabric uses view commands instead of setNativeProps. This diff removes what's left of setNativeProps from the core.
Reviewed By: JoshuaGross
Differential Revision: D24309999
fbshipit-source-id: 70e54f0a984f8c36f77ba2cd59f59fc6923bc832
Summary:
Exceptions in C++ work quite differently from exceptions in other languages. To make exceptions actually work **correctly** all the code needs to be written with "exceptions in mind" (e.g., see https://www.stroustrup.com/except.pdf). In short, if the code is not "exceptions ready", throwing an exception causes memory leaks, dangling pointers, and invariant violations all over the place, which will probably cause another crashes down the road (which will be especially hard to investigate and attribute to the original issue).
Fabric Core (Layout, Props parsing, ShadowNodes management, and so on) does not use exceptions because in most (all?) the cases the exception is now recoverable. So, if a program detects some internal state invariant violation or missing some resource, *logically* it's fatal. We also don't want to pay code-size and performance tax for exception support, so that's why we don't use them. It's just not the right fit for Fabric Core.
This does not mean that exceptions don't happen though. C++ standard library can throw them... sometimes. And if our library is compiled with exceptions enabled (still the case, unfortunately), an exception can bubble to JavaScript code and losing all context down the road. And it's hard to investigate such crashes. To isolate those occasional exceptions inside C++ core we are marking all C++/JS boundaries with `noexcept` that stops the bubbling.
I hope that will give us much more informative crash reports.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D23787492
fbshipit-source-id: 0822dbf36fc680c15b02b5cd0f2d87328296b642
Summary:
Under Fabric only, we can enter an infinite layout loop where the emitted layout event oscillates between two height values that are off by a very small amount.
The cause is, in part, components that use layoutEvents to determine their dimensions: for example, using onLayout event "height" parameters to determine the height of a child. If the onLayout height changes rapidly, the child's height will change, causing another layout, ad infinitum.
This might seem like an extreme case but there are product use-cases where this is done in non-Fabric and layout stabilizes quickly. In Fabric, currently it may never stabilize.
Part of this is due to a longstanding issue that exists in Fabric and non-Fabric, that we cannot immediately fix: If in a single frame, C++ emits 100 layout events to ReactJS, ReactJS may only process 50 before committing the root. That will trigger more layout events, even though product code has only partially processed the layout events. At the next frame, the next 50 events will be processed which may again change the layout, emitting more events... etc. In most cases the tree will converge and layout values will stabilize, but in extreme cases in Fabric, it might not.
Part of this is because Fabric does not drop *stale* layout events. If 10 layout events are dispatched to the same node, it will process all 10 events in older. Non-Fabric does not have this behavior, so we're changing Fabric to drop stale events when they queue up.
Changelog: [Internal]
Reviewed By: sammy-SC
Differential Revision: D23719494
fbshipit-source-id: e44a3b3e40585b59680299db3a4efdc63cdf0de8
Summary:
Fabric Core does not support exception safety, so technically exceptions are unrecoverable and binaries should be built without exception support.
While it's not the case, some exceptions might bubble to JavaScript realm and be caught as JavaScript exceptions. In this case, we lose the stack trace. To prevent that and to investigate one particular error we have we add this try-catch block in this diff.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D23529233
fbshipit-source-id: 7ac7fb26ac08ad26af8790172de471ac178c3a37
Summary:
Logbox inside bridgeless surfaces was crashing and not able to open, this diff should fix it.
Changelog: [Internal]
Reviewed By: PeteTheHeat
Differential Revision: D23043773
fbshipit-source-id: 6e584f97e53e626b9bfedd6dc997ba6ba8c08b8f
Summary:
There are a few places where we cast JSI values to objects without much validation and without proper error logging, and in some places the crashes aren't symbolicated well. To make debugging easier in the short-term, I'm adding some additional logs.
Changelog: [Internal]
Reviewed By: mdvacca, RSNara
Differential Revision: D23033222
fbshipit-source-id: 9343d693a441f0af728e560a0c245bcc4eb97869
Summary:
Changelog: [Internal]
Fabric's UIManager.measureInWindow didn't take viewport's offset into account. This diff fixes it by including viewport's offset in `LayoutContext`.
Reviewed By: JoshuaGross
Differential Revision: D23021903
fbshipit-source-id: 9106a8789d66fe19d8cb0a9378ee5bc8f2c83005
Summary:
Hook up onSuccess and onFailure callbacks to LayoutAnimations.
Note that in non-Fabric RN, onSuccess is not known to work in Android. I could not find any uses of onFailure and it's not documented, so for now, it is only called if the setup of the animation fails.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D22889352
fbshipit-source-id: 4306debb350388dd2b7a2cbfe295eb99723988e2
Summary:
This diff moves fabric C++ code from ReactCommon/fabric to ReactCommon/react/renderer
As part of this diff I also refactored components, codegen and callsites on CatalystApp, FB4A and venice
Script: P137350694
changelog: [internal] internal refactor
Reviewed By: fkgozali
Differential Revision: D22852139
fbshipit-source-id: f85310ba858b6afd81abfd9cbe6d70b28eca7415