Summary:
[Android] [Fixed] - LayoutAnimations cause invalid view operations
The dating team has found a consistent repro where following an order of steps will get you the following exception:
https://lookaside.facebook.com/intern/pixelcloudnew/asset/?id=2113362972287761
The exception is due to the fact that the following operation
`delete child tag 17 from parent tag 481 which is located at index 2`
cannot be performed because parent tag 481 only has 2 children.. and they also happen to not have the tag 17 as a child. Somehow the operations and the tree they act upon are out of sync.
RN receives operations from React via the native module `UIManagerModule`. The operations use tags (an identifier for a view) and indices to determine what view is updated. These operations (grouped together as a batch) are then passed to the UI thread where we perform them on the platform views.
LayoutAnimations are implemented per batch in RN. When LayoutAnimations are on, qualified view updates are animated. Because the delete operation is animated, RN doesn't remove the view from the platform view hierarchy immediately but asynchronously -- after the animation is complete. This is problematic for other view operations that rely on an index on where to insert or delete a view because during the creation of those operations, it was assumed all prior operations were performed synchronously.
This is what was occurring in the repro and there were silent view errors occurring before the exception was thrown.
This diff proposes a solution to track all pending delete operations across operations.
We introduce a map that is keyed on view tags and has a value of a sparse array that represents child index -> count of views that are pending deletion.
`{11: [0=1], 481: [2=1]}` where this would be interpreted as for index 0 under view tag 11, there is one async view deletion that has not completed and under tag 481 there is one async view deletion at index 2.
We use the map to adjust indices on add / delete operations. We also update the count when the deletion animation is complete and remove the tag from the map when it is deleted.
Regarding worst case sizing of the map => O(# of platform views rendered)
Reviewed By: mdvacca
Differential Revision: D14529038
fbshipit-source-id: 86d8982845e25a2b23d6d89ce27852fd77dbb060
Summary:
Instead of using measure specs to set certain yoga properties on the root node (like max width, auto width, specific width), use yoga's calculateLayout(width, height) instead. The measure specs will be stored in the shadow node. This allows us to remove duplicated code that processes the measure specs and allows us to remove other logic like the enableLayoutCalculation() method.
This diff also removes MeasureSpecProvider. MeasureSpecProvider was originally introduced to pass previously measured view measure specs to the initial creation of the root shadow node, but it turns out that this is unnecessary. We can update the root layout specs from the root view instead.
Reviewed By: mdvacca
Differential Revision: D9729744
fbshipit-source-id: 79b0b27ca879758f5dc3fc7cc8a0d38856a6cc79
Summary: SizeMonitoringFrameLayout was used to set layout contraints on the root shadow node when the native view's size changes. Since then, we introduced ways for the root node to use proper layout contraints using the root view's measure specs, which provides more accurate constraints for the root node, so SizeMonitoringFrameLayout is no longer needed. This ends up making a lot of UIManagerModule's method signatures cleaner
Reviewed By: mdvacca
Differential Revision: D9565720
fbshipit-source-id: c569cd15991a09987cc01e89612dc9193ad99b45
Summary: This diff reuses the ViewManager registry between UIManagerModule and Fabric, previously View Managers were being initialized twice (one for each UIManager), increasing Fabric TTI by ~77ms
Reviewed By: shergin
Differential Revision: D13640912
fbshipit-source-id: d7a9591084c66e4a2fc2384b2dae1b7fc5a228d0
Summary: This change drops the year from the copyright headers and the LICENSE file.
Reviewed By: yungsters
Differential Revision: D9727774
fbshipit-source-id: df4fc1e4390733fe774b1a160dd41b4a3d83302a
Summary:
There are multiple UI thread passes during the layout process. The first is with all of the operations from React (createView, manageChildren, etc). The second is during onCollectExtraUpdates after the layout pass, when things like Text need to be precomputed before later being sent over to the views.
The onLayoutUpdateListener needs to run AFTER onCollectExtraUpdates operations are executed, so this is now queued up in the UIViewOperationQueue
Reviewed By: mdvacca
Differential Revision: D9416260
fbshipit-source-id: d1a4eaf38a4f6c82d41def34ffb94d303e8f50d4
Summary:
In D8515300 we used the uiManagerType to call the setJSResponder method in UIImplementation or FabricUIManager.
There is a small chance that one of the reactTags received by parameter belongs to a View that is not managed by ReactNative, in that case we could be try to use FabricUIManager from UIManagerModule when Fabric is not running yet, causing a RN crash.
The fix consists in keep calling the UIImplementation.setJSResponder() method for any reactTag, and then perform a NOOP if the ReactShadowNode can not be found.
Reviewed By: fkgozali
Differential Revision: D8518192
fbshipit-source-id: 954fdd5dbed758ef73c16dad7da6b59ed83fe46a
Summary:
In native Android apps, like the YouTube app, context menus are closed when the device orientation changes.
In React Native apps instead, when having a [PopupMenu](https://developer.android.com/reference/android/widget/PopupMenu.html) open and rotating the device, the PopupMenu is not dismissed and appears in a wrong position on the screen.
This PR exposes a `dismissPopupMenu` method to allow the application to dismiss any open PopupMenu:
```(javascript)
UIManager.dismissPopupMenu()
```
Closes https://github.com/facebook/react-native/pull/15636
Differential Revision: D6837663
Pulled By: hramos
fbshipit-source-id: 7b0f4f04341129ad45c703a50897e17d93651974
Summary:
Includes React Native and its dependencies Fresco, Metro, and Yoga. Excludes samples/examples/docs.
find: ^(?:( *)|( *(?:[\*~#]|::))( )? *)?Copyright (?:\(c\) )?(\d{4})\b.+Facebook[\s\S]+?BSD[\s\S]+?(?:this source tree|the same directory)\.$
replace: $1$2$3Copyright (c) $4-present, Facebook, Inc.\n$2\n$1$2$3This source code is licensed under the MIT license found in the\n$1$2$3LICENSE file in the root directory of this source tree.
Reviewed By: TheSavior, yungsters
Differential Revision: D7007050
fbshipit-source-id: 37dd6bf0ffec0923bfc99c260bb330683f35553e
Summary:
Rebased version of #12842 that was reverted because of failing fb internal tests.
Closes https://github.com/facebook/react-native/pull/15919
Differential Revision: D5823956
Pulled By: hramos
fbshipit-source-id: 4ece19a403f5ebbe4829c4c26696ea0575ab1d0e
Summary:
Trivial.
That's okay that sometimes shadowNodes and views hierarchies have lack of synchonization.
Reviewed By: sahrens
Differential Revision: D6040022
fbshipit-source-id: 6b49a82317b620b66a87441719fddcafb1f27934
Summary:
In some cases we need a way to provide some peice of data to shadow node
to improve layout (or do something similar), `setLocalData` allows to do this.
Reviewed By: AaaChiuuu
Differential Revision: D5828368
fbshipit-source-id: bf6a04f460dc7695a16269426d365b78909bc8eb
Summary:
Add the ability for UIManager to check if a node is an ancestor of anther one on Android like #7876 did on iOS
Closes https://github.com/facebook/react-native/pull/13129
Differential Revision: D4938319
Pulled By: hramos
fbshipit-source-id: abe20779be2142a1ea9ac46f52d8cd8609236419
Summary:
See https://github.com/facebook/react-native/issues/10845
onSizeChanged is enqueueing a runnable from the ui thread that references a shadow view by id on the native modules thread. Since the shadow thread 'runs ahead' of the UI thread (e.g. it has a newer state of the world than the UI thread), this isn't safe. By the time that code block runs, it's possible that an update from JS has already removed that view from the shadow hierarchy (a change which would then propagate to the native hierarchy on the UI thread).
Reviewed By: AaaChiuuu
Differential Revision: D4706521
fbshipit-source-id: 0915f081068709b895f70b2edce12163b39e5456
Summary:
I don't remember exactly where we talked about this but LayoutAnimation on Android is pretty stable now so there's no reason to keep it behind an experimental flag anymore. The only part that is not really stable is delete animations, so what I did is remove the default delete animation that we provide in presets.
**Test plan**
Tested that layout animations work properly without any config.
Closes https://github.com/facebook/react-native/pull/12141
Differential Revision: D4494386
Pulled By: mkonicek
fbshipit-source-id: 5dd025584e35f9bff25dc299cc9ca5c5bf5f17a3
Summary: Adds a pool to recycle CSSNodes within UIManager. A follow-up diff will hook this up to a memory pressure listener to drop the pool on memory pressure.
Reviewed By: emilsjolander
Differential Revision: D4189532
fbshipit-source-id: 46583546f71a8c59853e1dd124de31657b3c617b
Summary:
This diff makes it so ReactShadowNode holds a CSSNode instead of extending one. This will enable us to pool and re-use CSSNodes and will allow us to keep from breaking the CSSNode api assumption that nodes that have measure functions don't have children (right now, text nodes have measure functions, but they also have raw text children).
BREAKING
This diff makes ReactShadowNode no longer extend CSSNodeDEPRECATED. If you have code that depended on that, e.g. via instanceof checks, that will no longer work as expected. Subclasses that override getChildAt/addChildAt/etc will need to update your method signatures. There should be no runtime behavior changes.
Reviewed By: emilsjolander
Differential Revision: D4153818
fbshipit-source-id: 2836434dd925d8e4651b9bb94b602c235e1e7665
Summary: This way `UIImplementation` can hold on to it and use it outside of calls from the `UIManagerModule`.
Reviewed By: lexs
Differential Revision: D3899774
fbshipit-source-id: 01e4956c4540bcdf30774a3f40a625e934714ee9