Fix Android Fabric sync prop null override#56913
Open
jingjing2222 wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
This fixes an Android Fabric crash in the synchronous mount props override path
used by
overrideBySynchronousMountPropsAtMountingAndroid.Repro repository:
https://github.com/jingjing2222/react-native-fabric-transform-repro
Context: we have been using
overrideBySynchronousMountPropsAtMountingAndroidenabled, following the same direction as the previous feature flag PR
#56652. While using the flag, we hit
a crash when a prop previously written by Native Animated is later cleared by a
regular Fabric props update.
The repro sequence is:
useNativeDriver: truesends a native animatedtransformupdate through thedirect manipulation path.
transformoverride for the view tag.transformfromthe same tag.
transform: null.map and in the incoming props update, then assumes the incoming value has the
same non-null type as the stored value.
For
transform, the stored value is an array, but the incoming value isnull.That currently crashes in
SurfaceMountingManager.overridePropsReadableMapwhiledispatching the Fabric mount item.
Observed Android logcat excerpt from the repro app:
The failing mount item is a regular Fabric props update for the same view tag:
This patch treats an incoming
nullvalue as a real React prop removal. When the incoming Fabric props update contains a key that also exists in the stored synchronous override map, and the incoming value isnull, the key is removed from the stored override map and thenullupdate is left intact.This is not limited to
transform. It also preserves the same prop-removal semantics foropacityand any future props stored by this path. If all stored keys for a tag are cleared, the per-tag override entry is also removed.Why this is correct
The synchronous override map is still required for normal native-driver updates. Native Animated can update the view on the UI thread before a stale regular Fabric commit arrives, and the stored override prevents that stale commit from resetting the latest animated value.
An incoming
nullis different from a stale animated value. It represents React removing the prop, which is the same semantic used by the JS-thread path whentransformdisappears from React props. In that case, the stored native override should not win; it should be dropped so the native view can reset the prop.Changelog:
[ANDROID] [FIXED] - Fix a Fabric synchronous mount props crash when a stored native animated prop is cleared by a null props update.
Test Plan:
Added regression coverage for clearing stored synchronous mount props with
incoming
nullFabric updates:updateProps_withNullOpacity_removesStoredSynchronousPropupdateProps_withNullTransform_removesStoredSynchronousPropRan:
Result:
Ran:
Result: