Commit 4d36e57
Fix Android Fabric Native Animated null prop crash (#56913)
Summary:
This fixes an Android Fabric crash in the `overrideBySynchronousMountPropsAtMountingAndroid` path when Native Animated has stored a synchronous `transform` / `opacity` override and a later regular Fabric commit contains `null` for the same prop.
| As-is | To-be |
| --- | --- |
| <img src="https://raw.githubusercontent.com/jingjing2222/react-native-fabric-transform-repro/main/crashed.gif" alt="Baseline Android Fabric transform crash repro" width="320" /> | <img src="https://raw.githubusercontent.com/jingjing2222/react-native-fabric-transform-repro/main/patched.gif" alt="Patched Android Fabric transform result" width="320" /> |
| [crashed.gif](https://github.com/jingjing2222/react-native-fabric-transform-repro/blob/main/crashed.gif) | [patched.gif](https://github.com/jingjing2222/react-native-fabric-transform-repro/blob/main/patched.gif) |
Native Animated can synchronously update `transform` / `opacity` on the UI thread. A regular Fabric commit for the same view may arrive later with stale props, including `transform: null` or `opacity: null`. Those regular Fabric null values should not clear the stored synchronous override, because the override may still represent the fresher Native Animated value.
Before this patch, the override merge path assumed that the incoming Fabric prop had the same non-null type as the stored override. For example, a stored `transform` override is an array, but a regular Fabric update may contain `transform: null`. That mismatch could crash in `SurfaceMountingManager.overridePropsReadableMap`.
This patch:
- Allows regular Fabric `null` updates to be overridden by stored synchronous `transform` / `opacity` values instead of crashing.
- Keeps regular Fabric `transform: null` / `opacity: null` from clearing the stored synchronous override.
- Scopes synchronous null clearing to `transform` / `opacity` only.
- Leaves null values for other props untouched, since other view prop nulls may be meaningful.
This PR intentionally does not change Java Native Animated `restoreDefaultValues()` behavior. That restore implementation can be handled separately because changing it may affect existing apps.
Repro repository:
https://github.com/jingjing2222/react-native-fabric-transform-repro
## Why this is correct
A regular Fabric `null` update is not enough to prove user intent to clear the native animated value, because it can be the stale commit produced after Native Animated already wrote a fresher value on the UI thread. In that case, the stored synchronous override should continue to win.
If the synchronous Native Animated path explicitly sends `transform: null` or `opacity: null`, this patch treats that as a clear signal for that stored override key. The clear behavior is intentionally scoped to the props currently stored by this override path.
```text
regular Fabric null: possible stale commit -> stored synchronous override wins
synchronous transform / opacity null: explicit clear -> stored override key is removed
other null props: left untouched
```
## Changelog:
[ANDROID] [FIXED] - Fix Android Fabric Native Animated crash when regular Fabric null props collide with stored synchronous transform or opacity overrides.
Pull Request resolved: #56913
Test Plan:
Added regression coverage for stale regular Fabric null commits and scoped synchronous null clears:
- `updateProps_withNullOpacity_keepsStoredSynchronousProp`
- `updateProps_withNullTransform_keepsStoredSynchronousProp`
- `updatePropsSynchronously_withNullOpacity_removesStoredSynchronousProp`
- `updatePropsSynchronously_withNullTransform_removesStoredSynchronousProp`
Ran:
```sh
./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest --tests com.facebook.react.fabric.SurfaceMountingManagerSynchronousMountPropsTest -Preact.internal.useHermesStable=true
```
Result:
```text
BUILD SUCCESSFUL
```
Ran:
```sh
./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest --tests com.facebook.react.animated.NativeAnimatedNodeTraversalTest -Preact.internal.useHermesStable=true
```
Result:
```text
BUILD SUCCESSFUL
```
Ran:
```sh
./gradlew :packages:react-native:ReactAndroid:ktfmtCheck -Preact.internal.useHermesStable=true
```
Result:
```text
BUILD SUCCESSFUL
```
Reviewed By: javache
Differential Revision: D105974289
Pulled By: zeyap
fbshipit-source-id: 7688cfa6b89f2d107c7ae58356864835d41f6add1 parent 54b9af1 commit 4d36e57
2 files changed
Lines changed: 135 additions & 12 deletions
File tree
- packages/react-native/ReactAndroid/src
- main/java/com/facebook/react/fabric/mounting
- test/java/com/facebook/react/fabric
Lines changed: 37 additions & 9 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
625 | 625 | | |
626 | 626 | | |
627 | 627 | | |
628 | | - | |
629 | | - | |
630 | | - | |
631 | | - | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
632 | 634 | | |
633 | | - | |
| 635 | + | |
634 | 636 | | |
635 | | - | |
636 | 637 | | |
637 | 638 | | |
638 | 639 | | |
| |||
1332 | 1333 | | |
1333 | 1334 | | |
1334 | 1335 | | |
1335 | | - | |
| 1336 | + | |
| 1337 | + | |
| 1338 | + | |
| 1339 | + | |
| 1340 | + | |
1336 | 1341 | | |
1337 | 1342 | | |
1338 | 1343 | | |
| |||
1350 | 1355 | | |
1351 | 1356 | | |
1352 | 1357 | | |
1353 | | - | |
| 1358 | + | |
| 1359 | + | |
| 1360 | + | |
| 1361 | + | |
| 1362 | + | |
1354 | 1363 | | |
1355 | 1364 | | |
1356 | 1365 | | |
1357 | 1366 | | |
1358 | 1367 | | |
1359 | 1368 | | |
1360 | | - | |
| 1369 | + | |
1361 | 1370 | | |
1362 | 1371 | | |
1363 | 1372 | | |
| |||
1387 | 1396 | | |
1388 | 1397 | | |
1389 | 1398 | | |
| 1399 | + | |
| 1400 | + | |
| 1401 | + | |
| 1402 | + | |
| 1403 | + | |
| 1404 | + | |
| 1405 | + | |
| 1406 | + | |
| 1407 | + | |
| 1408 | + | |
| 1409 | + | |
| 1410 | + | |
| 1411 | + | |
| 1412 | + | |
| 1413 | + | |
| 1414 | + | |
| 1415 | + | |
| 1416 | + | |
| 1417 | + | |
1390 | 1418 | | |
1391 | 1419 | | |
1392 | 1420 | | |
| |||
Lines changed: 98 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
| 16 | + | |
15 | 17 | | |
16 | | - | |
17 | 18 | | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| 23 | + | |
22 | 24 | | |
23 | 25 | | |
24 | 26 | | |
| |||
67 | 69 | | |
68 | 70 | | |
69 | 71 | | |
70 | | - | |
71 | | - | |
| 72 | + | |
| 73 | + | |
72 | 74 | | |
73 | 75 | | |
74 | 76 | | |
| |||
83 | 85 | | |
84 | 86 | | |
85 | 87 | | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
86 | 107 | | |
87 | 108 | | |
88 | 109 | | |
| |||
137 | 158 | | |
138 | 159 | | |
139 | 160 | | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
140 | 235 | | |
141 | 236 | | |
142 | 237 | | |
| |||
0 commit comments