Compare commits

..
Author SHA1 Message Date
Rob Hogan b55a871fa6 dev-middleware: Don't assume device-relative and debugger-relative URLs have the same port - remove CORS reliance
Summary:
Currently, if a device is connected to the bundler via, say, `http://10.0.2.2:8081` (Android default), and a debugger is opened on `http://localhost:8081`, we rewrite hostnames `10.0.2.2.`<->`localhost` so that URLs are correct relative to each.

However, if the debugger is on a different port or protocol, this breaks down - because we only rewrite hostnames.

This fixes that by using the debugger's connecting `Host` header and `encrypted` state to derive the base URL of the server relative to the frontend. We then update the rewriting logic to use this actual full origin (protocol + host) in place of the device-relative origin.

Changelog:
[General][Fixed] dev-middleware: Fix URL rewriting where device and debugger reach the server on different ports/protocols.

Differential Revision: D66077627
2024-11-21 07:10:15 -08:00
Rob Hogan 4effc43f41 dev-middleware: Refactor urlRegex rewriting, regex-escape IP4 addresses (#47872)
Summary:

Largely a refactoring to the way we currently rewrite `url`/`urlRegex` in `Debugger.setBreakpointByURL` CDP requests (debugger->target). 

Rewriting regexes is fragile, it only really works if we can assume `'localhost'` appears literally and that ports and protocols don't need changing. The intention here is to freeze the current behaviour so as not to break anyone relying on it (if anyone is), and decouple it from more robust rewriting we want to generalise.

Also adds simple regex escaping to host names (always IPv4 addresses) we inject into regex patterns, since the previous approach could've led to false matches in unlikely edge cases.

Changelog:
[General][Fixed] dev-middleware: Regex-escape IP addresses in urlRegex replacements

Reviewed By: huntie

Differential Revision: D66238782
2024-11-21 07:10:15 -08:00
209 changed files with 2497 additions and 3148 deletions
+1 -2
View File
@@ -44,7 +44,6 @@ packages/react-native/flow/
[options]
enums=true
as_const=true
casting_syntax=both
emoji=true
@@ -96,4 +95,4 @@ untyped-import
untyped-type-import
[version]
^0.255.0
^0.253.0
+1 -3
View File
@@ -421,9 +421,7 @@ jobs:
run-e2e-tests: ${{ github.ref == 'refs/heads/main' || contains(github.ref, 'stable') || inputs.run-e2e-tests }}
test_e2e_android_rntester:
# Temporarily disable RNTester tests on Android as they are quite flaky and they make CI always red
# if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, 'stable') || inputs.run-e2e-tests }}
if: ${{ contains(github.ref, 'stable') || inputs.run-e2e-tests }}
if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, 'stable') || inputs.run-e2e-tests }}
runs-on: ubuntu-latest
needs: [build_android]
strategy:
-392
View File
@@ -1,397 +1,5 @@
# Changelog
## v0.77.0-rc.0
### Breaking
- Bridgeless: Make NativeModules.foo load turbomodules (unset turboModuleProxy in bridgeless). ([cc5f17d5a2](https://github.com/facebook/react-native/commit/cc5f17d5a2b185de1e7dec2a56a97b088e4c7a81) by [@RSNara](https://github.com/RSNara))
- dev-middleware: Frameworks should specify `serverBaseUrl` relative to the middleware host. ([acf384a72e](https://github.com/facebook/react-native/commit/acf384a72e599691e4c9d53043f1801da01c58fd) by [@robhogan](https://github.com/robhogan))
- `position` of sticky headers on `ScrollView` will now be taken into account ([cbab004eb9](https://github.com/facebook/react-native/commit/cbab004eb94f8312e9b10dae1502d3ca8632a006) by [@joevilches](https://github.com/joevilches))
- Remove ReactFabricInternals module ([0c21db360c](https://github.com/facebook/react-native/commit/0c21db360cecc6a3265eea50d628106c58b67af8) by [@huntie](https://github.com/huntie))
- Make ReactDebugOverlayTags, DebugOverlayTags, Printer, PrinterHolder, NoopPrinter internal ([623d481991](https://github.com/facebook/react-native/commit/623d4819915e7e6fafb8006c8e3b3b796e394974) by [@cortinico](https://github.com/cortinico))
- More spec compliant absolute positioning ([0a2dec175e](https://github.com/facebook/react-native/commit/0a2dec175e92185943907f3e1f6073bae6cd663d) by [@NickGerleman](https://github.com/NickGerleman))
- Native looping animation will not send React state update every time it finishes. ([4b035d820d](https://github.com/facebook/react-native/commit/4b035d820d3f1c3c9a98ce4f55bcc95a7ab064bf) by [@dmytrorykun](https://github.com/dmytrorykun))
#### Android specific
- Removed ReactViewGroup.getBackgroundColor() ([6a472c5cf2](https://github.com/facebook/react-native/commit/6a472c5cf25d72f72ec7e261282d611a5ab0a662) by Thomas Nardone)
- ReadableArray non-primitive getters are now correctly typed as optional ([145c72f816](https://github.com/facebook/react-native/commit/145c72f8163048f0eee30d5ce850911f5dad865c) by [@javache](https://github.com/javache))
- Remove jsBundleLoader from DefaultReactHost.getDefaultReactHost() ([fbe4c0ed34](https://github.com/facebook/react-native/commit/fbe4c0ed347156a7ea24da29e09083a499c80cf5) by [@mdvacca](https://github.com/mdvacca))
- Reduce visibility of TaskCompletionSource class ([4f55161132](https://github.com/facebook/react-native/commit/4f551611326d63b6fb5cd53e63d536c2c6f04647) by [@mdvacca](https://github.com/mdvacca))
- Stable API - Make ImageStoreManager internal ([846c4b1ea2](https://github.com/facebook/react-native/commit/846c4b1ea2d139e3f3cbafa2f8ddbf159e3322e4) by [@arushikesarwani94](https://github.com/arushikesarwani94))
- Stable API - Make SwipeRefreshLayoutManager internal ([d02da992a4](https://github.com/facebook/react-native/commit/d02da992a4c0893313b9f059a8be228f43fffa7a) by Thomas Nardone)
- Undo breaking change of UiManager.eventDispatcher return type ([7817ab5de2](https://github.com/facebook/react-native/commit/7817ab5de2ce324df734a5dfd705f2454937328f) by [@cortinico](https://github.com/cortinico))
- Stable API - Make classes inside `com.facebook.react.views.progressbar` internal ([46526fc2fe](https://github.com/facebook/react-native/commit/46526fc2fe1dd0ce937fad35469b64b9fb05eaa2) by [@cortinico](https://github.com/cortinico))
- Undo breaking change of UiManager.eventDispatcher return type ([dbe509a23a](https://github.com/facebook/react-native/commit/dbe509a23a974f16804aefea055a24c06910b259) by [@cortinico](https://github.com/cortinico))
- Stable API - Make OkHttpCallUtil internal ([abd118a719](https://github.com/facebook/react-native/commit/abd118a719fe0aeb13f980729ff9ce5fb8358b83) by [@arushikesarwani94](https://github.com/arushikesarwani94))
- Stable API - Make SimpleSettableFuture internal ([3dec672398](https://github.com/facebook/react-native/commit/3dec672398729cd668aff92249f1fdde231fb928) by [@arushikesarwani94](https://github.com/arushikesarwani94))
- Stable API - Make `ClipboardModule` internal ([10f6d5adb5](https://github.com/facebook/react-native/commit/10f6d5adb538a9b20043312fc09b192759100d63) by [@cortinico](https://github.com/cortinico))
- Reduce visibility of ReactVirtualTextShadowNode to internal ([496b0a8729](https://github.com/facebook/react-native/commit/496b0a8729b41266683fdd84de5618b23d06ce3d) by [@mdvacca](https://github.com/mdvacca))
- Reduce visibility of ReactVirtualTextViewManager to internal ([4a119c4c3a](https://github.com/facebook/react-native/commit/4a119c4c3ac9bf4b234e2942a27a6efd68a801cc) by [@mdvacca](https://github.com/mdvacca))
- Stable API - Make classes in `com.facebook.react.views.safeareaview` internal ([39dfbadd5d](https://github.com/facebook/react-native/commit/39dfbadd5d3468d079bf3b039401237c6e7f363c) by [@cortinico](https://github.com/cortinico))
- Stable API - Make ClipboardModule internal ([a72c35f98c](https://github.com/facebook/react-native/commit/a72c35f98ccd1a49d367678b46a29c814ad5de43) by [@cortinico](https://github.com/cortinico))
- Undo a breaking change on ReactViewGroup constructor ([bbe714e487](https://github.com/facebook/react-native/commit/bbe714e487fb51c61820fdc5d89c9782da79b657) by [@cortinico](https://github.com/cortinico))
- Stable API - Make NativeModulePerfLogger internal ([d7d5de9f96](https://github.com/facebook/react-native/commit/d7d5de9f9630e7dcd0194830d7ccb32f167b619c) by [@cortinico](https://github.com/cortinico))
- Make `DevLoadingModule` internal ([8c50bf0beb](https://github.com/facebook/react-native/commit/8c50bf0beb17ced7fdafeae7a734edfc03e6e0b2) by [@cortinico](https://github.com/cortinico))
- Stable API - Convert to Kotlin and make internal `NotThreadSafeViewHierarchyUpdateDebugListener` ([287e200332](https://github.com/facebook/react-native/commit/287e20033207df5e59d199a347b7ae2b4cd7a59e) by [@cortinico](https://github.com/cortinico))
- Rename DevSupportManagerBase.getCurrentContext() -> getCurrentReactContext() ([0e7ba9094e](https://github.com/facebook/react-native/commit/0e7ba9094ea573d1512b2dc71e46f55b24201b7a) by [@RSNara](https://github.com/RSNara))
- Make DevSupportManagerBase.getCurrentReactContext() public ([5a6a42c7d0](https://github.com/facebook/react-native/commit/5a6a42c7d029d44799cb907c0ca3c8aa38fa1770) by [@RSNara](https://github.com/RSNara))
- Reduce visibility of ReactUnimplementedViewManager to internal ([fe656be26e](https://github.com/facebook/react-native/commit/fe656be26e0d71bf2505032578dbea54af36b2c5) by [@mdvacca](https://github.com/mdvacca))
- Stable API - Make InteropModuleRegistry internal ([cba1d4bae7](https://github.com/facebook/react-native/commit/cba1d4bae7285ba160b05f31ca18cfa0b91e9ef5) by [@cortinico](https://github.com/cortinico))
- Stable API - Make ReactDevToolsSettingsManagerModule and ReactDevToolsRuntimeSettingsModule internal ([d7550293a2](https://github.com/facebook/react-native/commit/d7550293a2530f02f75b4249b7e6003edaf28ac9) by [@cortinico](https://github.com/cortinico))
- Added JSBundleLoader as parameter of DefaultReactHost ([143b9d172c](https://github.com/facebook/react-native/commit/143b9d172ca755e2457e8dfc6009eeef2475a4a1) by [@mdvacca](https://github.com/mdvacca))
- Deleting deprecated CompositeReactPackage ([2cb5198f1b](https://github.com/facebook/react-native/commit/2cb5198f1b589a57a4cfd3cc40a9ed6224fc5d75) by [@mdvacca](https://github.com/mdvacca))
- Make ReactHost.createSurface() method non nullable ([70c7616535](https://github.com/facebook/react-native/commit/70c761653564653bdfcb77a8c5ef3608dafcf5d7) by [@mdvacca](https://github.com/mdvacca))
- Stable API - Make AppStateModule internal ([dbf09fbe58](https://github.com/facebook/react-native/commit/dbf09fbe5823d77556b451317c14f833735067d9) by [@cortinico](https://github.com/cortinico))
- Undo breaking change on UIManager eventDispatcher accessor ([dc1a498d39](https://github.com/facebook/react-native/commit/dc1a498d3974680f2257efd8ff9ec3f989204c68) by [@cortinico](https://github.com/cortinico))
- Make `AccessibilityInfoModule` internal ([7168a9d1a2](https://github.com/facebook/react-native/commit/7168a9d1a2ed7459ebb056ebe45d86de791013e3) by [@cortinico](https://github.com/cortinico))
- Undo breaking change on ViewManagerDelegate.kt String params ([2d2bb9c588](https://github.com/facebook/react-native/commit/2d2bb9c58824af34392bda196fbf0be17498cc05) by [@cortinico](https://github.com/cortinico))
- Add 3 methods to ReactInstanceDevHelper ([c867aba2f3](https://github.com/facebook/react-native/commit/c867aba2f3dd7773be9d2ee0827bcd69481a394e) by [@cortinico](https://github.com/cortinico))
- Add test case for set opacity in new arch examples ([848471b69f](https://github.com/facebook/react-native/commit/848471b69f59094780ace25c6963e480d94ec5c3) by [@poonamjain96](https://github.com/poonamjain96))
- Add test for Console.log measure in new-arch-examples ([8cf27e8b6f](https://github.com/facebook/react-native/commit/8cf27e8b6f112d646111ddaba0b5036cafac3299) by [@poonamjain96](https://github.com/poonamjain96))
- Remove Deprecated DefaultDevSupportManagerFactory.create() ([f25abe51ce](https://github.com/facebook/react-native/commit/f25abe51ce93b97ef1fe97af5fc76f13a5a6ff03) by [@cortinico](https://github.com/cortinico))
- Remove BaseViewManagerInterface ([7fb3d830be](https://github.com/facebook/react-native/commit/7fb3d830beae3daf431ac90e9326b744ff8300a1) by [@NickGerleman](https://github.com/NickGerleman))
- Chore: test case added for Image ([d0e5053528](https://github.com/facebook/react-native/commit/d0e50535287088030e60e131691c8d9ed1d57989) by [@sarthak-d11](https://github.com/sarthak-d11))
- Remove ReactNativeFlipper object, deprecated in 0.75 ([d1a256f51a](https://github.com/facebook/react-native/commit/d1a256f51a43f465823bdfb8a70fae5f92473d7c) by [@cortinico](https://github.com/cortinico))
- Add test for background color and border width in text.yml ([fa62b7e1ed](https://github.com/facebook/react-native/commit/fa62b7e1ed00c69819d85819c6209fb42bedb233) by [@muskan27797](https://github.com/muskan27797))
- Added Submit Application test to button.yml ([699f73a6b0](https://github.com/facebook/react-native/commit/699f73a6b0734fe716b01d263e9579bca38c4652) by [@shubhamguptadream11](https://github.com/shubhamguptadream11))
- Use BackgroundStyleApplicator when setting background color in BaseViewManager ([309cdea337](https://github.com/facebook/react-native/commit/309cdea337101cfe2212cfb6abebf1e783e43282) by [@NickGerleman](https://github.com/NickGerleman))
- Delete useTurboModules, enableFabricRenderer and enableBridgelessArchitecture fields from ReactFeatureFlags class ([10a33e0479](https://github.com/facebook/react-native/commit/10a33e04793befbeab6ae82d4068b1ebd7fdffd0) by [@mdvacca](https://github.com/mdvacca))
- Remove ReactViewBackgroundManager and ReactViewBackgroundDrawable ([51673e41ae](https://github.com/facebook/react-native/commit/51673e41ae12f06b2b378e048094ad39ca30c317) by [@NickGerleman](https://github.com/NickGerleman))
#### iOS specific
- Use the RCTDependencyProvider in the RCTAppDelegate, breaking the dependency with Codegen ([b91626af26](https://github.com/facebook/react-native/commit/b91626af2626bf611958b1e7d0dd0b7338ccc29e) by [@cipolleschi](https://github.com/cipolleschi))
- Delete experimental API RCTConstants.RCTGetMemoryPressureUnloadLevel ([d79dc48abd](https://github.com/facebook/react-native/commit/d79dc48abd2e65e4d203e488f99eb554c473a1fc) by [@mdvacca](https://github.com/mdvacca))
- ([6fc500ee99](https://github.com/facebook/react-native/commit/6fc500ee9942e51519545c1ba1026bacad03dc61) by [@philIip](https://github.com/philIip))
- ([538bff710f](https://github.com/facebook/react-native/commit/538bff710f7afb4afa7ce91f20074668ad5c739d) by [@philIip](https://github.com/philIip))
- Replace uses of `CGColorRef` with UIColor to avoid manual memory management ([b70709dbc2](https://github.com/facebook/react-native/commit/b70709dbc27c75c69e9fd2b082ffa27e7e8db7fd) by [@Saadnajmi](https://github.com/Saadnajmi))
- Cocoapods decide the C++ version for iOS pods ([bd50c4a460](https://github.com/facebook/react-native/commit/bd50c4a460a01dad3cd7cade8191273563675d24) by [@cipolleschi](https://github.com/cipolleschi))
- Delete partialBatchDidFlush ([a777a8937e](https://github.com/facebook/react-native/commit/a777a8937ee165993d7d9b35c7c981fe6698f9dc) by [@philIip](https://github.com/philIip))
- We deprecated RCTRuntimeExecutor in 0.76, so let's get rid of the code now. ([cf8d09b279](https://github.com/facebook/react-native/commit/cf8d09b279c4bd667d96f9445c1c0b9acb0a0dfc) by [@philIip](https://github.com/philIip))
- Unbreak `RCTHermesInstance` constructor breaking change ([aec6666bfa](https://github.com/facebook/react-native/commit/aec6666bfabf93cde70fa869b3eea68590998dee) by [@tido64](https://github.com/tido64))
### Added
- Add FuseboxPerfettoDataSource to emit Fusebox traces using Perfetto ([ef0ea4d834](https://github.com/facebook/react-native/commit/ef0ea4d834ec61c5deede487b46a787a363f6a64) by Benoit Girard)
- Add support for `rn_rootThreshold` in Intersection Observer ([a77d8d9d50](https://github.com/facebook/react-native/commit/a77d8d9d50e69a6a4563737c2ce68d26204eda7f) by [@lunaleaps](https://github.com/lunaleaps))
- Codegen: Support negative values in enums ([177bf4d043](https://github.com/facebook/react-native/commit/177bf4d043ce862911e477e0f0039214d8541cfd) by [@okwasniewski](https://github.com/okwasniewski))
- Use the TypeScript key in syntax to restrict permissions and types of results ([0244710c4b](https://github.com/facebook/react-native/commit/0244710c4b1e5016069ec9f7b8e7116ff51f59f1) by [@qnnp-me](https://github.com/qnnp-me))
- Image `resizeMode` and `objectFit` support for `'none'`. ([d8cfd98070](https://github.com/facebook/react-native/commit/d8cfd98070cbccc5e8a49446d76bdc2cb0c6939f) by [@mateoguzmana](https://github.com/mateoguzmana))
- Add NumberLiteralTypeAnnotation support ([dd472101b7](https://github.com/facebook/react-native/commit/dd472101b76a964b7a64f0bb84d967f702500cad) by [@elicwhite](https://github.com/elicwhite))
- Eliminate usage of more than 1-arg `React.AbstractComponent` in React codebase ([6205aad81e](https://github.com/facebook/react-native/commit/6205aad81ef8154a106fa253a1f4b00aee568650) by [@SamChou19815](https://github.com/SamChou19815))
- Added support for `display: contents` ([e7a3f479fe](https://github.com/facebook/react-native/commit/e7a3f479fe37a5d503770bafc03c80b1c2dcb8f7) by [@j-piasecki](https://github.com/j-piasecki))
- Added the missing `announceForAccessibilityWithOptions` function mock in the `packages/react-native/jest/setup.js` file. ([4ae999b90b](https://github.com/facebook/react-native/commit/4ae999b90b2a67233890d30a8bff0dbdd58364f2) by [@ChrisMattew](https://github.com/ChrisMattew))
- Add support for reload-to-profile in Fusebox (Part 2 of 2: JS) ([4df224ca6d](https://github.com/facebook/react-native/commit/4df224ca6df9dc593ab7090520578f27c520f361) by [@EdmondChuiHW](https://github.com/EdmondChuiHW))
- Add JS layer for new text content type cellular EID and cellular IMEI ([118c1f7035](https://github.com/facebook/react-native/commit/118c1f7035cfcadb567b1ccd40d85c751dd65162) by [@cipolleschi](https://github.com/cipolleschi))
- Add support for reload-to-profile in Fusebox. (Part 1 of 2: native) ([91a40a28de](https://github.com/facebook/react-native/commit/91a40a28de3f74a389c6e6ad05fb917d58fc072d) by [@EdmondChuiHW](https://github.com/EdmondChuiHW))
- Add cli --help details to combine-js-toschema-cli.js ([e4814b0d6d](https://github.com/facebook/react-native/commit/e4814b0d6d981cf96eef2803e8f20548263ea0e4) by [@blakef](https://github.com/blakef))
- Codegen for Native Modules now supports string literals ([d2f3f06826](https://github.com/facebook/react-native/commit/d2f3f06826e2287ad5f5dc4e27201fc5dc9fcd5c) by [@elicwhite](https://github.com/elicwhite))
- Codegen now supports Union Types in NativeModules ([3af126b562](https://github.com/facebook/react-native/commit/3af126b562cf7e0828906a4fe0ac79a886b557e6) by [@elicwhite](https://github.com/elicwhite))
- Updated FlatList setNativeProps type ([b0ac99b477](https://github.com/facebook/react-native/commit/b0ac99b47781e3b68bee2ff737b109f58eeeba78) by [@JDMathew](https://github.com/JDMathew))
- Added Jest mocks for `NativeAnimatedModule` ([fd355308fa](https://github.com/facebook/react-native/commit/fd355308faa2da30d4e0d68ae9b4d136d2a5f1c3) by [@yungsters](https://github.com/yungsters))
- Added `HostInstance` type to represent the instance of a `HostComponent<T>`. ([e24f9917c2](https://github.com/facebook/react-native/commit/e24f9917c25ed8c32c6e01d50a5fa49fe66a6ee1) by [@yungsters](https://github.com/yungsters))
- Export `DevMenu` from `react-native` ([e12c0d9551](https://github.com/facebook/react-native/commit/e12c0d95516924b5e6ca4f0d5ebcadb42bb19f30) by [@frankcalise](https://github.com/frankcalise))
- Removed `experimental` prefix and fully released `mixBlendMode` prop ([d2c48f3b1a](https://github.com/facebook/react-native/commit/d2c48f3b1a2a15e9832ea3240c19aea5186ceb24) by [@jorge-cab](https://github.com/jorge-cab))
- Add Playground to RNTester for testing out features & submitting reproducers. ([256adcab7b](https://github.com/facebook/react-native/commit/256adcab7b02e8a80227d44b76d1a74d8c4973de) by [@shwanton](https://github.com/shwanton))
- Add color formatting to codegen output ([1747f57c67](https://github.com/facebook/react-native/commit/1747f57c6708ffa59ea511f9fbbacf37364fde72) by [@okwasniewski](https://github.com/okwasniewski))
- Added overlayColor prop to modal component for customisable background overlay ([4e1d7015c1](https://github.com/facebook/react-native/commit/4e1d7015c1d4e2703133b1347ed97a0cc93b1318) by [@shubhamguptadream11](https://github.com/shubhamguptadream11))
- Created an experimental optimization to improve memoization within `Animated` to improve product performance ([dc84d00db6](https://github.com/facebook/react-native/commit/dc84d00db64b78234e91c2b73f4d4fce8782cd02) by [@yungsters](https://github.com/yungsters))
- Expose missing text content type to JS ([d3d48cb357](https://github.com/facebook/react-native/commit/d3d48cb357e55b1f2ae0042a5960451fbe5ff5c7) by [@cipolleschi](https://github.com/cipolleschi))
- Created an experimental (unstable) method for allowlisting props when using `Animated` ([f3f652daab](https://github.com/facebook/react-native/commit/f3f652daabc4a1d374190165ac38715ad31a5214) by [@yungsters](https://github.com/yungsters))
- Upgrade Flow to 0.245.2 ([1f65bf9545](https://github.com/facebook/react-native/commit/1f65bf9545cd84bbf1be7a7a91cb0b4f8b4b47ba) by [@SamChou19815](https://github.com/SamChou19815))
#### Android specific
- Image `force-cache` caching control option ([a0be88fd72](https://github.com/facebook/react-native/commit/a0be88fd727898d4626ca51876d0bfb4e50dcb77) by [@mateoguzmana](https://github.com/mateoguzmana))
- Add overlapping radii resolution logic preventing incorrect rendering ([451ff70da4](https://github.com/facebook/react-native/commit/451ff70da422beefccfff5b87024145003bb49ff) by [@jorge-cab](https://github.com/jorge-cab))
- Marked ReactPackage#getModule as stable. ([8fba7ebb5e](https://github.com/facebook/react-native/commit/8fba7ebb5e874d001dc5c16eb4229054a2ef4812) by [@javache](https://github.com/javache))
- ReactDelegate and ReactActivityDelegate#getCurrentReactContext can be used to access the current context ([fe8cc62824](https://github.com/facebook/react-native/commit/fe8cc62824372229d90445b2769fed9c08604a7e) by [@javache](https://github.com/javache))
- Add exceptionHandler as a parameter of DefaultReactHost.getDefaultReactHost() method ([7a5a10c95c](https://github.com/facebook/react-native/commit/7a5a10c95ce6af1964ce5bd273c0c6513fb78a1e) by [@mdvacca](https://github.com/mdvacca))
- Logic to check for grayscale mode on android ([e70202e606](https://github.com/facebook/react-native/commit/e70202e606be3101da33d28f5403443c3e84749e) by [@oddlyspaced](https://github.com/oddlyspaced))
- TextTransform ktx ([7794d7af43](https://github.com/facebook/react-native/commit/7794d7af43b90b581574361af102f67ad7961a5e) by Thomas Nardone)
- Add navigationBarTranslucent prop to Modal component ([7a6c7a462a](https://github.com/facebook/react-native/commit/7a6c7a462a7898e13327438a6603d83a39147abb) by [@zoontek](https://github.com/zoontek))
- Trigger Java GC on app reload ([de3c1ee097](https://github.com/facebook/react-native/commit/de3c1ee097f7041d6f9754a55a45cea80fd25813) by [@mrousavy](https://github.com/mrousavy))
- Add cmake arguments to support 16KB page size for native libraries ([65cdd5b82c](https://github.com/facebook/react-native/commit/65cdd5b82ce7652630b1920fa3a48c8f256c7983) by [@alanleedev](https://github.com/alanleedev))
- Enabling basic `Image` cache control for Android ([e5dd7d68bf](https://github.com/facebook/react-native/commit/e5dd7d68bf264669fc5c4ce5e69b24249d28558b) by [@mateoguzmana](https://github.com/mateoguzmana))
- Add OnLayoutChange API for scroll views ([d825a4d712](https://github.com/facebook/react-native/commit/d825a4d712a1ba53c0f4209c9da5d51578209a6d) by Thomas Nardone)
- React Activity exposes ReactHost ([d78cb78b15](https://github.com/facebook/react-native/commit/d78cb78b15a520f3bebcdf00b82b26bf120f4180) by [@shwanton](https://github.com/shwanton))
- Added PixelUtil extensions for Int and Long ([9406a09f87](https://github.com/facebook/react-native/commit/9406a09f871d3efa66e3d10237a6d1fd08ddee0b) by Thomas Nardone)
- Add boxShadow support to BaseViewManager ([b69a92e2c9](https://github.com/facebook/react-native/commit/b69a92e2c95990fcfa95a6ab7b7260ac492f942c) by [@NickGerleman](https://github.com/NickGerleman))
- Test: pressable test cases ([3102a58df3](https://github.com/facebook/react-native/commit/3102a58df38d96f3dacef0530e4dbb399037fcd2) by [@deepanshushuklad11](https://github.com/deepanshushuklad11))
- Added showcase for Android `resizeMethod` options when applied to a large image ([768a1d8664](https://github.com/facebook/react-native/commit/768a1d86649e391964d404a15733c227c57c0d38) by [@Abbondanzo](https://github.com/Abbondanzo))
- Adds a new `resizeMethod`, `none`, which disables downsampling for an image ([6202319ed5](https://github.com/facebook/react-native/commit/6202319ed544e4d23f1f327ff5334c480af3819d) by [@Abbondanzo](https://github.com/Abbondanzo))
- Add Modal Testing to modal.yml ([1a2532b1fc](https://github.com/facebook/react-native/commit/1a2532b1fc32ec989e05576121b5e669697d29af) by [@ahmedbilal008](https://github.com/ahmedbilal008))
- Add a new Fresco decoder for XML resource types ([118b7c18a6](https://github.com/facebook/react-native/commit/118b7c18a6f827dabb00522bbd6a2416e1bf99da) by [@Abbondanzo](https://github.com/Abbondanzo))
- Added `isHighTextContrastEnabled()` to `AccessibilityInfo` to read `ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED` setting value ([d4ea147b41](https://github.com/facebook/react-native/commit/d4ea147b41e4d22253f80be8b74731dcf0439302) by Ariel Lin)
- Outline properties `outline-width`, `outline-color`, `outline-style` & `outline-offset` ([17faac4170](https://github.com/facebook/react-native/commit/17faac417035f2cc5f12ec60a46270991be0989a) by [@jorge-cab](https://github.com/jorge-cab))
- Flag in ReactFragment to allow unmounting a surface without destroying ReactHost. ([bb3ec4d6c3](https://github.com/facebook/react-native/commit/bb3ec4d6c342d3afcb109e8c65f99e7693c962b5) by [@rozele](https://github.com/rozele))
- ReactDelegate `unloadApp` methods for unmounting surfaces without destroying ReactHost ([38593c440e](https://github.com/facebook/react-native/commit/38593c440e949a9b52df0a6821b80ac47b19a693) by [@rozele](https://github.com/rozele))
- New feature flag for line height calculation ([f338e7c0a1](https://github.com/facebook/react-native/commit/f338e7c0a1072974b5ac76567c8d1d06f5b7c1e2) by [@mellyeliu](https://github.com/mellyeliu))
- Adds support for importing XML assets as images ([2e80f5acf1](https://github.com/facebook/react-native/commit/2e80f5acf11cd9726921a00a58700cab9e0bb0a7) by [@Abbondanzo](https://github.com/Abbondanzo))
#### iOS specific
- Image `only-if-cached` cache control option ([dc9db01665](https://github.com/facebook/react-native/commit/dc9db01665308ac931967326abfc86deb9ae7e2a) by [@mateoguzmana](https://github.com/mateoguzmana))
- TextInput `inputAccessoryViewButtonLabel` prop ([32931466ed](https://github.com/facebook/react-native/commit/32931466ed7e3d8d9eeeb65f12ce146e123870ba) by [@mateoguzmana](https://github.com/mateoguzmana))
- Fix: Correct Layout Behavior for Combined align-content and align-items ([73a2be1243](https://github.com/facebook/react-native/commit/73a2be12437c93bbd138e0d63cd45d834529a3c4) by [@phuccvx12](https://github.com/phuccvx12))
- Extract RCTAppDependencyProvider in the ReactAppDependencyProvider pod ([102062fbc7](https://github.com/facebook/react-native/commit/102062fbc7d6a5c81192562c3ccb87bc4222a0cf) by [@cipolleschi](https://github.com/cipolleschi))
- Pass the `RCTAppDependencyProvider` to the `RCTAppDelegate` ([95fc906930](https://github.com/facebook/react-native/commit/95fc906930ece9b30482eb1f0924d7e8614af7c6) by [@cipolleschi](https://github.com/cipolleschi))
- Introduce the RCTAppDependencyProvider to minimize the changes required y the users ([41c2502b36](https://github.com/facebook/react-native/commit/41c2502b3650e238b0a5d86b5044abcb538b76e3) by [@cipolleschi](https://github.com/cipolleschi))
- Add RCTDependencyProvider protocol ([f2b3716426](https://github.com/facebook/react-native/commit/f2b371642684682916522dc82adee93464ba31fe) by [@cipolleschi](https://github.com/cipolleschi))
- Added `disabledButtonTintColor` prop to ActionSheetIOS ([089c87e22e](https://github.com/facebook/react-native/commit/089c87e22e9f431d0e7f35292dce2e36fa86d09a) by [@henninghall](https://github.com/henninghall))
- Scroll the cursor into view when text input is focused ([e021e50d53](https://github.com/facebook/react-native/commit/e021e50d537884a55a9f5bea931adb19e9069dd6) by [@dominictb](https://github.com/dominictb))
- Introduce RCTArchConfiguratorProtocol ([ec0dbb729d](https://github.com/facebook/react-native/commit/ec0dbb729d3774184dee83efbff5f9beebce72ce) by [@okwasniewski](https://github.com/okwasniewski))
- Introduce RCTUIConfiguratorProtocol ([8850736188](https://github.com/facebook/react-native/commit/8850736188321f13c7bdeadedeed15c759ad72c1) by [@okwasniewski](https://github.com/okwasniewski))
- TvOS support for Hermes artifacts ([f673759c83](https://github.com/facebook/react-native/commit/f673759c83fed130964ea7dfe677c04608b8e64d) by [@douglowder](https://github.com/douglowder))
- Add `CallInvoker` to `BindingsInstaller` ([87bae7f734](https://github.com/facebook/react-native/commit/87bae7f7349976cfc269b25584330c4d3d897d79) by [@mrousavy](https://github.com/mrousavy))
- Added `isDarkerSystemColorsEnabled()` to `AccessibilityInfo` to read "Increase Contrast" setting value ([af3bee6511](https://github.com/facebook/react-native/commit/af3bee6511fe72fda7415bf974f937012b3eefec) by Ariel Lin)
- Expose RCT_NEW_ARCH_ENABLED to Swift ([d24507611d](https://github.com/facebook/react-native/commit/d24507611de7fefc71286fd54b2c909d98a4bf27) by [@okwasniewski](https://github.com/okwasniewski))
- Add `systemCyan` and `systemMint` colors on iOS ([4caf548a9f](https://github.com/facebook/react-native/commit/4caf548a9f2e485aef9cbaeeb0a666cf9b9d3e59) by [@EvanBacon](https://github.com/EvanBacon))
- Outline properties `outline-width`, `outline-color`, `outline-style` & `outline-offset` ([1288e38423](https://github.com/facebook/react-native/commit/1288e38423f93ed57737dd9b40ad55696494d6f4) by [@jorge-cab](https://github.com/jorge-cab))
- Declare supportedInterfaceOrientations only on iOS ([40c5e6b64a](https://github.com/facebook/react-native/commit/40c5e6b64a1d82b5b481717b9086340eca2aaef9) by [@okwasniewski](https://github.com/okwasniewski))
- New text content type cellular EID and cellular IMEI ([14e0d0dffb](https://github.com/facebook/react-native/commit/14e0d0dffb9ee8b1d41d60ccbcfd63d53bfe4d48) by [@pasc0al](https://github.com/pasc0al))
- User-configurable BUNDLE_NAME when building bundles ([f8287e25e1](https://github.com/facebook/react-native/commit/f8287e25e11d56beb66ace414ca5f8a6a32405a9) by [@fivecar](https://github.com/fivecar))
- Line break mode for TextInput components. **This includes JS APIs for the new mode.** ([ce2d34f194](https://github.com/facebook/react-native/commit/ce2d34f19451c91a90f0bd820064208912c86092) by [@shubhamguptadream11](https://github.com/shubhamguptadream11))
### Changed
- Fixed a typo in the README file. ([30e75a51f3](https://github.com/facebook/react-native/commit/30e75a51f3af7fbad83e4b002526b69bba021753) by [@Aryan2727-debug](https://github.com/Aryan2727-debug))
- Fix unnececary rerenders of VirtualizedListCells with strictMode={true} ([aafe696453](https://github.com/facebook/react-native/commit/aafe696453186d0e87ae96d0bca4c6650234d222) by [@Tom910](https://github.com/Tom910))
- The `AnimatedNode` graph will not occur during the insertion effect phase, which means animations can now be reliably started during layout effects. ([316170ce8d](https://github.com/facebook/react-native/commit/316170ce8d0aac1df3261c792b9f768665d134c5) by [@yungsters](https://github.com/yungsters))
- AttributedString `appendFragment` and `prependFragment` take an rval instead of a const ref; append/prependAttributedString have been removed ([2c31fe99e1](https://github.com/facebook/react-native/commit/2c31fe99e1cc5bfdb393d4f5c70231a042ea67ef) by [@javache](https://github.com/javache))
- Improved AttributedText generation for raw text nodes. ([2f7957f2fd](https://github.com/facebook/react-native/commit/2f7957f2fd424fdaa980d99a4ff05eb3237d662e) by [@javache](https://github.com/javache))
- Callbacks passed to `animation.start(<callback>)` will be scheduled for execution in a microtask. Previously, there were certain scenarios in which the callback could be synchronously executed by `start`. ([090501d26d](https://github.com/facebook/react-native/commit/090501d26d83be5c5d2df885c60d05ec133d7a54) by [@yungsters](https://github.com/yungsters))
- Optimized the performance of updating `Animated` components. ([f0ffcd4f5d](https://github.com/facebook/react-native/commit/f0ffcd4f5dfeab794fbfa3257bb9a8fd793ff2bc) by [@yungsters](https://github.com/yungsters))
- Bump serve-static to 1.16.2 to fix CVE-2024-43800 ([50e38cc9f1](https://github.com/facebook/react-native/commit/50e38cc9f1e6713228a91ad50f426c4f65e65e1a) by [@cortinico](https://github.com/cortinico))
- Bump Folly to 2024.10.14.00 ([37375d8aba](https://github.com/facebook/react-native/commit/37375d8aba0869531567426466478b0de9a1aea3) by [@alanleedev](https://github.com/alanleedev))
- `useMergeRefs` and components using it (e.g. `Pressable`) now support ref cleanup functions. ([01e210fd28](https://github.com/facebook/react-native/commit/01e210fd28bc961e8c1b5fa454b3c947adda296c) by [@yungsters](https://github.com/yungsters))
- : Update Metro to 0.81.0 ([0902b0af75](https://github.com/facebook/react-native/commit/0902b0af75ba30ec9d4abeda71769d0685637afa) by [@robhogan](https://github.com/robhogan))
- Animations started with incompatible `useNativeDriver` and `AnimatedValue` configurations will now synchronously fail. Previously, spring and timing animations with non-zero delays would throw the error asynchronously. ([fd8cf19625](https://github.com/facebook/react-native/commit/fd8cf1962585aa49e8921475d89c1a5c2423c51c) by [@yungsters](https://github.com/yungsters))
- The `Animation` superclass no longer exposes `__onEnd` as a property. Subclasses must instead invoke `super.start(…)` in their `start()` implementation. ([b3fe06b268](https://github.com/facebook/react-native/commit/b3fe06b2685e526fe2bc420a902a3ccd4e1381df) by [@yungsters](https://github.com/yungsters))
- Simplified Flow types to use `HostInstance` (which changing nominal types). ([177697f539](https://github.com/facebook/react-native/commit/177697f539ec68a47cbb8f57260cebe701589ef1) by [@yungsters](https://github.com/yungsters))
- Upgrade React DevTools to 6.0.0. ([ed4f6d6891](https://github.com/facebook/react-native/commit/ed4f6d68910677ab050e3fef5aaa87e42d582fe0) by [@hoxyq](https://github.com/hoxyq))
- Fix: use public instance in Fiber renderer and expose it from getInspectorDataForViewAtPoint (#31068) ([633ad4933e](https://github.com/facebook/react-native/commit/633ad4933e9514d4168d6dcdb7e56c9a1859482a) by [@hoxyq](https://github.com/hoxyq))
- Get react-native package name from package.json in codegen script ([65575e8399](https://github.com/facebook/react-native/commit/65575e8399a08841a0ccbc5b28cafeee6d41714c) by [@okwasniewski](https://github.com/okwasniewski))
- Bring back shouldSkipStateUpdatesForLoopingAnimations feature flag ([6e0e712c2a](https://github.com/facebook/react-native/commit/6e0e712c2a680cf4b4de1ee5fb25cc5282b242c5) by [@dmytrorykun](https://github.com/dmytrorykun))
- AnimatedNode (and its subclasses) once again implement `toJSON()`. ([7bd4a54968](https://github.com/facebook/react-native/commit/7bd4a5496815943b031b68ca46792560d8d798d8) by [@yungsters](https://github.com/yungsters))
- Do not print Bridgeless Mode is enabled on console anymore ([f3a969f38d](https://github.com/facebook/react-native/commit/f3a969f38d7a2c74bf63ee05c4c819c0873059a9) by [@cortinico](https://github.com/cortinico))
- Bump main to 0.77-main ([120558c0cd](https://github.com/facebook/react-native/commit/120558c0cd6ae50156d2f7b958d3a29fd7ae4623) by [@cipolleschi](https://github.com/cipolleschi))
- Improved the performance of unmounting (and updating, when an enclosing Activity becomes hidden) Animated components ([46abda55b9](https://github.com/facebook/react-native/commit/46abda55b9749dc171e0fec551ba83c027818eb7) by Royi Hagigi)
- AnimatedNode (and its subclasses) no longer implement `toJSON()`. ([fe6228512e](https://github.com/facebook/react-native/commit/fe6228512e076820c9c11869cfe24b19d1abfb58) by [@yungsters](https://github.com/yungsters))
- Animated now resolves `style` to the original prop value if it contains no `AnimatedNode` instances. Previously, it would resolve to a flattened style object. ([ca234ba10e](https://github.com/facebook/react-native/commit/ca234ba10e8d06630da7ea00aac515b222137645) by [@yungsters](https://github.com/yungsters))
- Bump Metro dependencies to 0.81.0-alpha.0 ([40f98b5eee](https://github.com/facebook/react-native/commit/40f98b5eeef18bb9c20a9a2762d0b1d648c4ae91) by [@robhogan](https://github.com/robhogan))
#### Android specific
- Consolidated ReactViewGroup add/remove overrides ([0b22b955f1](https://github.com/facebook/react-native/commit/0b22b955f1494f0e7441a01dd19b3fdf5e20c3dc) by Thomas Nardone)
- Migrated systeminfo module code from Java to Kotlin ([8dc2c90ce5](https://github.com/facebook/react-native/commit/8dc2c90ce5f4b30f4729560aed2412e6d29f39fa) by [@oddlyspaced](https://github.com/oddlyspaced))
- Updating targetSdk to 35 (apps can still choose their own targetSdk regardless of RN version) ([48ea6867a9](https://github.com/facebook/react-native/commit/48ea6867a96bd16dc7aed9af5a8e9ce12a487c22) by [@alanleedev](https://github.com/alanleedev))
- Invocations to JS will now invoke their callbacks immediately if the instance is ready. Surface starts will not wait for the main thread to become available to dispatch the work in JS. ([9fa4845136](https://github.com/facebook/react-native/commit/9fa4845136969ec95ce5615b7ea78feaf0f7f109) by [@javache](https://github.com/javache))
- TurboModules marked as requiring eager init will now be constructed on the mqt_native thread to increase concurrency in React Native init. ([663b5f9d19](https://github.com/facebook/react-native/commit/663b5f9d19a905520bd0aef62cda890f76ef9b6e) by [@javache](https://github.com/javache))
- Reduce visibility of Continuation to internal, although this interface wasn't being exposed in any public API ([7b21b9e69c](https://github.com/facebook/react-native/commit/7b21b9e69c6176c7f66af0e479623ed1c2be0d62) by [@mdvacca](https://github.com/mdvacca))
- Update documentation for ReactHost.destroy() APIs ([443bc32dc4](https://github.com/facebook/react-native/commit/443bc32dc49a86534fce1d6ec0e31c97b8f33053) by [@mdvacca](https://github.com/mdvacca))
- Deprecate CatalystInstance in old architecture ([3e27ef1f6e](https://github.com/facebook/react-native/commit/3e27ef1f6e024bba8725a3bd64e2648ffd6af496) by [@mdvacca](https://github.com/mdvacca))
- Deprecate BridgelessCatalystInstance class ([72bd840dd3](https://github.com/facebook/react-native/commit/72bd840dd3dc7b6e3e88a74ac9ddb000a0cb3a60) by [@mdvacca](https://github.com/mdvacca))
- AGP to 8.7.2 ([e1a1cead43](https://github.com/facebook/react-native/commit/e1a1cead434a6856b2b018274876b9ba8eab706a) by [@cortinico](https://github.com/cortinico))
- Migrate ReactFeatureFlags to Kotlin ([4076dbfc86](https://github.com/facebook/react-native/commit/4076dbfc8651fcd193b886bf63b23728fad466d7) by [@mdvacca](https://github.com/mdvacca))
- Android NDK to 27.1 ([ba061a5d18](https://github.com/facebook/react-native/commit/ba061a5d18176fd455c3aa6350127506dac05211) by [@alanleedev](https://github.com/alanleedev))
- Migrate MainReactPackage to Kotlin (and make it final) ([7bbac8ee27](https://github.com/facebook/react-native/commit/7bbac8ee27daf092b580b57c2c7ee46d2723cd09) by [@cortinico](https://github.com/cortinico))
- Bump fbjni to 0.7.0 ([1c002c7b4e](https://github.com/facebook/react-native/commit/1c002c7b4ea4f22729920e54a9032402247ea350) by [@alanleedev](https://github.com/alanleedev))
- Fresco to 3.4.0 ([091025e18b](https://github.com/facebook/react-native/commit/091025e18b1dc5212031e3ed06bfb6c450e788e2) by [@cortinico](https://github.com/cortinico))
- Bump Kotlin 1.9.x to 2.0.x ([972c2c864c](https://github.com/facebook/react-native/commit/972c2c864c0b563163a36080a13908d1c0a3fb87) by [@cortinico](https://github.com/cortinico))
- Fix: change opacity logic from random to decrement by -0.20 ([af4907025e](https://github.com/facebook/react-native/commit/af4907025ef358c312d469118a52699dcf14507d) by [@sarthak-d11](https://github.com/sarthak-d11))
- Bump Android Gradle Plugin (AGP) to 8.7.0 ([cbc0978bb6](https://github.com/facebook/react-native/commit/cbc0978bb65dcfd2a18a54201c845785a626b1b3) by [@cortinico](https://github.com/cortinico))
- Improve FpsDebugFrameCallback.getTotalTimeMS() accuracy ([d54c25fdae](https://github.com/facebook/react-native/commit/d54c25fdaee4d2642cdbca812b61c6973d3f203d) by [@aamagda](https://github.com/aamagda))
- Update Fresco from 3.2.0 to 3.3.0 ([86d92e41d2](https://github.com/facebook/react-native/commit/86d92e41d2e129d12589848f75dfe2b2db09ed1a) by [@Abbondanzo](https://github.com/Abbondanzo))
- Disabling `outline` props on Android to stay consistent with iOS ([7ab0002799](https://github.com/facebook/react-native/commit/7ab0002799d52a876a8cdd32f25ebef6d431650e) by [@jorge-cab](https://github.com/jorge-cab))
- Gradle to 8.10.1 ([90f89a830a](https://github.com/facebook/react-native/commit/90f89a830acced9e6b8e80ef58aefd7e2c9666a8) by [@cortinico](https://github.com/cortinico))
#### iOS specific
- Make `prefetchImageWithMetadata`'s `queryRootName` nullable in the spec ([4dd60acb7d](https://github.com/facebook/react-native/commit/4dd60acb7ddc2811453e84e3567c1a114fa5e6f9) by [@TheRogue76](https://github.com/TheRogue76))
- Change how components automatically register ([8becc2514d](https://github.com/facebook/react-native/commit/8becc2514d484c99b51ea76f479f06a8fcdd8265) by [@cipolleschi](https://github.com/cipolleschi))
- Stop generating the RCTThirdPartyLibraryComponentProvider ([60b9d3d89e](https://github.com/facebook/react-native/commit/60b9d3d89eba90a945070646c6220b3c03b3aeba) by [@cipolleschi](https://github.com/cipolleschi))
- `RCTSurfaceHostingProxyRootView` no longer has different behavior (whether it calls `start` on the provided *surface*) depending on which initializer is used. Call `start` yourself on the *surface* instead. ([13b93cfdda](https://github.com/facebook/react-native/commit/13b93cfddaa559697968ac1c19e55f7aaa053070) by Nolan O'Brien)
- Use `newArchEnabled` flag in RCTAppDelegate and RCTRootViewFactory ([7e1674fc59](https://github.com/facebook/react-native/commit/7e1674fc59abeeb70d946ee082a829fae4c671b7) by [@okwasniewski](https://github.com/okwasniewski))
- Do not move to the main queue synchronously when starting a new surface ([ab2c47be28](https://github.com/facebook/react-native/commit/ab2c47be285fde99a77d189fd04220ef8ad0933a) by [@cipolleschi](https://github.com/cipolleschi))
- Rename `RCTUIGraphicsImageRenderer` to `RCTMakeUIGraphicsImageRenderer` ([6a09fc09af](https://github.com/facebook/react-native/commit/6a09fc09af8eedbf409ab870d5714e44892b2a16) by [@Saadnajmi](https://github.com/Saadnajmi))
- Refactor RCTDevLoadingView to use constraints ([fbda60e657](https://github.com/facebook/react-native/commit/fbda60e65783d9a3f257cd427cbffc1c9b2cc01b) by [@okwasniewski](https://github.com/okwasniewski))
### Deprecated
#### Android specific
- Deprecated shadows for ReadableNative[Map|Array].[Readable|Writable] ([d424bb9d7c](https://github.com/facebook/react-native/commit/d424bb9d7cf101dc5609e8f787ba8af2a33d0262) by [@javache](https://github.com/javache))
- ReactContext.getFabricUIManager() method ([fb737ca7d3](https://github.com/facebook/react-native/commit/fb737ca7d34b636a3aa337a0935bf9a5a10c641d) by [@mdvacca](https://github.com/mdvacca))
#### iOS specific
- Deprecating RCTBridgeModule batchDidComplete and adding configuration to disable it ([731bd95c43](https://github.com/facebook/react-native/commit/731bd95c430c752126aaaa34e4911ba2b87b382f) by [@philIip](https://github.com/philIip))
### Removed
- Remove `BackHandler.removeEventListener` ([44d619414c](https://github.com/facebook/react-native/commit/44d619414c1de3dbf17a421afa8dbcec7cdab025) by [@retyui](https://github.com/retyui))
- Removed type for useConcurrentRoot from AppRegistry, as it was already ignored ([2ec547ad28](https://github.com/facebook/react-native/commit/2ec547ad28ca914c17e276abb91174dfa0dc87b2) by [@javache](https://github.com/javache))
- Remove "run on iOS" and "run on Android" from the dev server key commands ([19b971ff94](https://github.com/facebook/react-native/commit/19b971ff94a0fe353f82363e788c13f86815663b) by [@huntie](https://github.com/huntie))
- Removed `refs` property from `NativeMethods` TypeScript definition. ([223e98cc4b](https://github.com/facebook/react-native/commit/223e98cc4b656b94b48c88940114bfdc025f8ddf) by [@yungsters](https://github.com/yungsters))
#### Android specific
- Removed hasConstants constructor from ReactModuleInfo ([aec7a66ae8](https://github.com/facebook/react-native/commit/aec7a66ae84bd7689d902686711db8eabc21c1f1) by [@javache](https://github.com/javache))
- Removed TurboReactPackage, which was replaced by BaseReactPackage ([bf5c98cf5e](https://github.com/facebook/react-native/commit/bf5c98cf5e1ce5c041d3d9321a0ba2fd3c755b46) by [@javache](https://github.com/javache))
- DevToolsReactPerfLogger stats gathering now uses an internal API ([f503fe3f10](https://github.com/facebook/react-native/commit/f503fe3f100d96a31fc56451d7846d80ce5c342f) by [@javache](https://github.com/javache))
- BindingImpl is no longer part of the public interface ([18faf68b48](https://github.com/facebook/react-native/commit/18faf68b4825118253cf247572084c4da8f6366e) by [@javache](https://github.com/javache))
- FabricComponents is removed from public API ([300db67b27](https://github.com/facebook/react-native/commit/300db67b270a5d6fc85d27188d0d1089675f89c0) by [@javache](https://github.com/javache))
#### iOS specific
- Remove available for RCTKeyWindow check ([e98c221e5e](https://github.com/facebook/react-native/commit/e98c221e5e54e79c25acd06f14e7d01221823305) by [@okwasniewski](https://github.com/okwasniewski))
### Fixed
- Hermes: revert Intl removal ([4cffff35e0](https://github.com/facebook/react-native/commit/4cffff35e030f256c32bf69c5971dfee4e60723f) by [@robhogan](https://github.com/robhogan))
- Fix the nodes' owners not being updated when `display: contents` is used ([aa53bde21b](https://github.com/facebook/react-native/commit/aa53bde21b8952533cf17ffee234b273766f2133) by [@j-piasecki](https://github.com/j-piasecki))
- dev-middleware: Rewrite URLs in the inspector proxy to cover all configurations, not just Android emulators. ([74995bc90a](https://github.com/facebook/react-native/commit/74995bc90aa039b880e4875ad356d3bce324d902) by [@robhogan](https://github.com/robhogan))
- Fix C++ bridging template compatibility with MSVC ([e6848ba5ba](https://github.com/facebook/react-native/commit/e6848ba5ba997d102cbaf6181c7c8c73e25a0827) by [@acoates-ms](https://github.com/acoates-ms))
- Accessing KeyboardAvoidingEvent event in onLayout handler ([68db74205a](https://github.com/facebook/react-native/commit/68db74205afdd190304eb73ef71710781fa580b9) by [@mhoran](https://github.com/mhoran))
- dev-middleware: Fix URL rewriting where device and debugger reach the server on different ports/protocols. ([5da7ebf99a](https://github.com/facebook/react-native/commit/5da7ebf99ae317c104d8e4bfbf36d3d89f66b5c9) by [@robhogan](https://github.com/robhogan))
- dev-middleware: Regex-escape IP addresses in urlRegex replacements ([aae3e03e57](https://github.com/facebook/react-native/commit/aae3e03e57096c3dc51589a3de240d49a8b9fadf) by [@robhogan](https://github.com/robhogan))
- Fixed jest error from Appearance.js ([ce838a4bcf](https://github.com/facebook/react-native/commit/ce838a4bcfb1c08728b637a9addd24cc6e3477e0) by [@Kudo](https://github.com/Kudo))
- When using Babel with plain JavaScript files, support for additional user syntax plugins should be fixed (now uses Babel's parser instead of hermes-parser). There is no change for JS files annotated with `flow`, where extended JS syntax remains unsupported. ([3de9892353](https://github.com/facebook/react-native/commit/3de989235365504468d2b6c0bb194e944bf1ce8e) by [@huntie](https://github.com/huntie))
- Fix `Appearance.setColorScheme(null)` not resetting color scheme value ([7d63235086](https://github.com/facebook/react-native/commit/7d63235086352d8c424d634c7039551f0a5025dc) by [@sangonz193](https://github.com/sangonz193))
- Fix text not taking full width ([550b0c0ed1](https://github.com/facebook/react-native/commit/550b0c0ed16a64ce58102f15d4657abe92aac71c) by [@s77rt](https://github.com/s77rt))
- Linear gradient start and end point algorithm. ([221d1eceda](https://github.com/facebook/react-native/commit/221d1eceda0e5ab870e96dcdd26e22ab17a3870c) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway))
- Codegen: Support nested objects in arrays ([13780126d3](https://github.com/facebook/react-native/commit/13780126d3cb17ad00c2954f9830a3623812dc3e) by [@tvanlaerhoven](https://github.com/tvanlaerhoven))
- RN DevTools: Don't assume 10.0.2.2 is an alias for localhost unless it's used to establish a connection to the server ([69400be4fc](https://github.com/facebook/react-native/commit/69400be4fc0abd38072f6586f3e7d5b6c33e54be) by [@robhogan](https://github.com/robhogan))
- Do not discard props in the patch when they are not null while using `useNativeProps` ([4c3112c8d8](https://github.com/facebook/react-native/commit/4c3112c8d8685d6c34be9acf07b18871b3cee5b2) by [@cipolleschi](https://github.com/cipolleschi))
- : dev-middleware: Remove URL.canParse, restore compat with Node < 18.17 ([99767d43b0](https://github.com/facebook/react-native/commit/99767d43b04e41c83e3bcbfebe267d6fdc284549) by [@robhogan](https://github.com/robhogan))
- RN DevTools: Fix fetching sources and source maps when the dev-server is remote and not tunnelled via the same port+protocol. ([d1b0e9a30b](https://github.com/facebook/react-native/commit/d1b0e9a30b3afc56b9355453cf7f6e690bdd8aff) by [@robhogan](https://github.com/robhogan))
- Fix npm react-native start when cli-server-api isn't installed ([e0be2efe4e](https://github.com/facebook/react-native/commit/e0be2efe4e80edf99f96a2ae6a25856f6df5e0ca) by [@blakef](https://github.com/blakef))
- AnsiHighlight style in RTL layout ([9a3958a619](https://github.com/facebook/react-native/commit/9a3958a619fddb75ed3c6eddebd94f11c0d00e9f) by [@hexboy](https://github.com/hexboy))
- Fixes typo in ReactHostImpl ([e3f03269c5](https://github.com/facebook/react-native/commit/e3f03269c5cea28977e44ddf5c5125968336b0e6) by [@rozele](https://github.com/rozele))
- TextTransform: capitalize better reflects the web behaviour ([dc2000c875](https://github.com/facebook/react-native/commit/dc2000c8750f42b2f01bdad75455750814d567c6) by [@javache](https://github.com/javache))
- Fix for nodes with `display: contents` not being cleaned in some cases ([a88ddcecc9](https://github.com/facebook/react-native/commit/a88ddcecc93a9fa2d231907439d02b11bac8a944) by [@j-piasecki](https://github.com/j-piasecki))
- Microtasks are now correctly executed after the code evaluation in Console panel of DevTools. ([3dfe22bd27](https://github.com/facebook/react-native/commit/3dfe22bd27429a43b4648c597b71f7965f31ca65) by [@hoxyq](https://github.com/hoxyq))
- Passed height and width as native props to support cases where source is an array. ([45b177f50d](https://github.com/facebook/react-native/commit/45b177f50de624eefcb66bb2d8bc1ffb00855863) by [@shubhamguptadream11](https://github.com/shubhamguptadream11))
- `PerformanceEntryReporter::reportMark` and `PerformanceEntryReporter::reportMeasaure` now return created performance entries. ([32f7b3b4e0](https://github.com/facebook/react-native/commit/32f7b3b4e0b8be1d1138f43c46b3c86d9a64c29a) by [@robik](https://github.com/robik))
- Make Codegen work with local modules ([7b6e8e7765](https://github.com/facebook/react-native/commit/7b6e8e776574e683821133f0c814969d74c4de61) by [@cipolleschi](https://github.com/cipolleschi))
- Fix KeyboardAvoidingView not aware of the keyboard closing it is unmounted ([08bd8ac47d](https://github.com/facebook/react-native/commit/08bd8ac47da60121225e7b281bbf566e2c5a291e) by [@QichenZhu](https://github.com/QichenZhu))
- Fix onEndReached not being called when getItemLayout is present and we scroll past render window ([3485e9ed87](https://github.com/facebook/react-native/commit/3485e9ed871886b3e7408f90d623da5c018da493) by YunPeng Chong)
- Fix cast and control paths errors on windows ([0794fa909b](https://github.com/facebook/react-native/commit/0794fa909b2e06fad5c40dce402c5f14a24bb946) by [@TatianaKapos](https://github.com/TatianaKapos))
- Plumbing to get boxSizing prop to Yoga round 2 ([3ca796edc3](https://github.com/facebook/react-native/commit/3ca796edc327c5287533dcc8f4394033d5398c2d) by [@joevilches](https://github.com/joevilches))
- Fix onEndReached not being called when getItemLayout is present and we scroll past render window ([62b7396bf4](https://github.com/facebook/react-native/commit/62b7396bf45c04bd47e74fe4c1e5b5e59918244d) by [@NickGerleman](https://github.com/NickGerleman))
- TurboModule::get is now a final method, override `create` to customize property lookup ([5b5e150eaf](https://github.com/facebook/react-native/commit/5b5e150eaff015540720225b9e61acb306e1d107) by [@javache](https://github.com/javache))
- Improved types for AnimatedProps ([390925ea39](https://github.com/facebook/react-native/commit/390925ea39eb469768f21cf7069b8f75ccdec09d) by [@javache](https://github.com/javache))
- Upgrade Codegen dependency `jscodeshift@17.0.0` to resolve outdated dependencies ([39c98fb8f8](https://github.com/facebook/react-native/commit/39c98fb8f8af98aa40dc89a1580d6c1901fa86cf) by [@byCedric](https://github.com/byCedric))
- Fixed issues with W3C PointerEvents testsx ([1dcaf823f5](https://github.com/facebook/react-native/commit/1dcaf823f5e7d9b114dd803ce3181aa0b8f827ad) by [@rozele](https://github.com/rozele))
- Fixed issue with W3C PointerEvents tests ([68a6b69b27](https://github.com/facebook/react-native/commit/68a6b69b27275998b4083797942f3e26a92d3adb) by [@rozele](https://github.com/rozele))
- Fix setImmediate/clearTimeout mismatch in NativeAnimatedHelper that could clear an unrelated setTimeout. ([a5dd1be889](https://github.com/facebook/react-native/commit/a5dd1be889be21f8daefbc609702989ec7c156cf) by Benoit Girard)
- Improved error message when no view config is found. ([bca232ad90](https://github.com/facebook/react-native/commit/bca232ad90692da7a87be5e37ee2680380f94bef) by [@javache](https://github.com/javache))
- : Order of operations related to platformConfig propagation in NativeAnimated ([a64183b0c6](https://github.com/facebook/react-native/commit/a64183b0c6a56e9d482c7b8b0f80965493ed87af) by [@rozele](https://github.com/rozele))
- Rename overlayColor prop in Modal to backdropColor ([7aeff18970](https://github.com/facebook/react-native/commit/7aeff18970a2b47cbb3fffc1408e4bb21eec6fed) by [@alanleedev](https://github.com/alanleedev))
- Fix source mapping for codegenNativeCommands ([8fba154b66](https://github.com/facebook/react-native/commit/8fba154b6655b5d87609d7c9f136997141ea5e99) by [@vzaidman](https://github.com/vzaidman))
- Fixed accuracy of FlatList estimations to determine what elements are visible in the rendering window. ([40aaeb7181](https://github.com/facebook/react-native/commit/40aaeb71814a1987482d97fd3170af0add55bc6a) by [@rubennorte](https://github.com/rubennorte))
- Fix type conversion error in react native windows build. ([13db1cb88b](https://github.com/facebook/react-native/commit/13db1cb88bdd454cf19be358d6f0cd62f5a6d0cc) by [@marlenecota](https://github.com/marlenecota))
- Correctly pass down isLooping in parallel animation ([4014aa4528](https://github.com/facebook/react-native/commit/4014aa4528d43e905246850c83007a635938d7cb) by [@zeyap](https://github.com/zeyap))
#### Android specific
- Yoga: Fix YogaConfig getting garbage collected #1678 ([7dcb10b6e7](https://github.com/facebook/react-native/commit/7dcb10b6e7e226034a496eaed5351601ae0a1ae2) by [@michaeltroger](https://github.com/michaeltroger))
- Enable mix-blend-mode on ReactRootView so blending works with app background ([24b0ded3cf](https://github.com/facebook/react-native/commit/24b0ded3cf715bb0e849d9f7ca8cd2d4d42cbf90) by [@jorge-cab](https://github.com/jorge-cab))
- RN DevTools: Fix source loading when using an Android emulator connecting to a dev server on the host. ([ca9c56329f](https://github.com/facebook/react-native/commit/ca9c56329fe548b6631934afee0c9be63e1752a1) by [@robhogan](https://github.com/robhogan))
- Fixes some deadlocks when doing commits and state updates synchronously from the UI thread (e.g.: from reanimated). ([3986eefed1](https://github.com/facebook/react-native/commit/3986eefed1733f305db5410737a96b635f0159e7) by [@rubennorte](https://github.com/rubennorte))
- Ensure setSelection in onAttachedToWindow is within text range ([08759121cd](https://github.com/facebook/react-native/commit/08759121cda3785e4d7ee1f1c82011a3e3a955a9) by [@zeyap](https://github.com/zeyap))
- Fixed crash in legacy ReactFontManager ([3da23f7093](https://github.com/facebook/react-native/commit/3da23f7093730e10aeda6b58f4934a381e226dd2) by [@javache](https://github.com/javache))
- Dispatch onMomentumScrollEnd after programmatic scrolling ([c69e330324](https://github.com/facebook/react-native/commit/c69e330324724a1e363f4786b2b03ee7ff4b35c5) by [@Biki-das](https://github.com/Biki-das))
- RNGP - Do not attempt to substring to 1024 while logging ([e64513bf4e](https://github.com/facebook/react-native/commit/e64513bf4ecce60aff5c04e3bed91b203429d12f) by [@cortinico](https://github.com/cortinico))
- Missing isInvertColorsEnabled implementation for Android ([cc1d2853fb](https://github.com/facebook/react-native/commit/cc1d2853fb2b64adfb884cb30c8d22ce0260be15) by [@oddlyspaced](https://github.com/oddlyspaced))
- Addressed race condition in surface start. ([6ba7cb3102](https://github.com/facebook/react-native/commit/6ba7cb310273a0ecce6a168bf3aae45fb85bf955) by [@javache](https://github.com/javache))
- The definition of ts of resizeMethod attribute is none. ([758892a7d8](https://github.com/facebook/react-native/commit/758892a7d89cc1e316984f8f522738021410f530) by [@nianxiongdi](https://github.com/nianxiongdi))
- Reimplement Android lineHeight positioning/determination ([41265bac6b](https://github.com/facebook/react-native/commit/41265bac6b83ee0bb92d645ace81e314065bf5e0) by [@NickGerleman](https://github.com/NickGerleman))
- Fix legacy arch RTL horizontal ScrollView regression ([bfca7cfe7a](https://github.com/facebook/react-native/commit/bfca7cfe7a8e0da10fdb776100fbc706233c0d8d) by [@NickGerleman](https://github.com/NickGerleman))
- Fix RTL ScrollView position when content smaller than container ([0df59d4f03](https://github.com/facebook/react-native/commit/0df59d4f03f79c0fcb9ede2d21bf4d49c97c21ef) by [@NickGerleman](https://github.com/NickGerleman))
- Avoid null reference exception in bridgeless ReactDelegate ([0d664100bb](https://github.com/facebook/react-native/commit/0d664100bbf608550a5c42a4e9b02c6c5bd0f5b8) by [@rozele](https://github.com/rozele))
- Fix generating empty line at the end of multiline text view when `textAlign` is set to `justify` ([08e8f6adfd](https://github.com/facebook/react-native/commit/08e8f6adfdcdfec59002f34bb7acf35bb842b331) by [@coado](https://github.com/coado))
- Fix Frame Callback not being called after Host Resume ([e8f8ee3c0f](https://github.com/facebook/react-native/commit/e8f8ee3c0f28b8c5751ffaef495adea0b8daf1eb) by [@s77rt](https://github.com/s77rt))
- Fix crash in getViewState when using suspense fallbacks. ([bd133b5dd5](https://github.com/facebook/react-native/commit/bd133b5dd57b18140eae51c6d7aaab02874455c1) by [@javache](https://github.com/javache))
- Text without explicit font styles was potentially cut-off. ([95a5d1c628](https://github.com/facebook/react-native/commit/95a5d1c6287c7301265207d1962ba8b50d178b20) by [@javache](https://github.com/javache))
- Merge Android ViewNativeComponent ViewConfig into BaseViewConfig ([0ba00fc998](https://github.com/facebook/react-native/commit/0ba00fc99891a333d3625db15d9dd832ca7eac88) by [@NickGerleman](https://github.com/NickGerleman))
- Fixed styling on alert dialog titles to wrap two lines and retain bold appearance ([c54b23ff9e](https://github.com/facebook/react-native/commit/c54b23ff9ed7a6bfbb52c081c5afe4b3911d0dd2) by [@Abbondanzo](https://github.com/Abbondanzo))
- Prevent ArrayIndexOutOfBoundsException in permission check ([6aeca53b3e](https://github.com/facebook/react-native/commit/6aeca53b3ed4530e57a31d7a5593ae16b550b985) by [@antFrancon](https://github.com/antFrancon))
- Account for items dynamically scaling with the container when using `maintainVisibleContentPosition` in virtualized lists ([6c19996e10](https://github.com/facebook/react-native/commit/6c19996e10eda97a3501f53a68da246d1f122d01) by [@fabriziocucci](https://github.com/fabriziocucci))
- Apps will no longer fatally crash when trying to draw large images ([483b928224](https://github.com/facebook/react-native/commit/483b92822496fa2e6339f75049a33be1e9567f52) by [@Abbondanzo](https://github.com/Abbondanzo))
- Add missing BaseViewManager props to BaseViewManagerDelegate ([6741fd94ad](https://github.com/facebook/react-native/commit/6741fd94ad26012938caa65a5129f0eca6f2246e) by [@NickGerleman](https://github.com/NickGerleman))
- Fix TextInput caret moving to the beginning when attached to window ([ca0abd1b9e](https://github.com/facebook/react-native/commit/ca0abd1b9ea164a566b39cb9090eaa75647aad5a) by [@QichenZhu](https://github.com/QichenZhu))
- Fix issue where `onDropViewInstance` cleanup was not being handled after `ReactRootView.unmountReactApplication` ([0449630612](https://github.com/facebook/react-native/commit/04496306123c46730b46accb2cd6239531e51fef) by [@rozele](https://github.com/rozele))
- Fix issues with Modals and lifecycle events in multi-surface apps ([1ffef5669c](https://github.com/facebook/react-native/commit/1ffef5669c21f4b2c5fec6bc58a85f95518cf10e) by [@rozele](https://github.com/rozele))
- Fix mising `ANTI_ALIAS_FLAG` when resetting Text Paint ([276e3a7df7](https://github.com/facebook/react-native/commit/276e3a7df7de1b04dec0891fa7ed72917568ee7b) by [@NickGerleman](https://github.com/NickGerleman))
- Fix some cases where we override setBackgroundColor on View-level instead of VM level ([0b0ac81fbe](https://github.com/facebook/react-native/commit/0b0ac81fbeebf819e744b6ecc19d549aaab8406d) by [@NickGerleman](https://github.com/NickGerleman))
- Avoid blocking the main thread when decompressing drawable resources ([420229d669](https://github.com/facebook/react-native/commit/420229d66946320f06485c5a3d3c167eae1a407e) by [@Abbondanzo](https://github.com/Abbondanzo))
- Reenable `setAndroidLayoutDirection` by default ([6cf0cfb5a4](https://github.com/facebook/react-native/commit/6cf0cfb5a47a437b8a17b50b4c70460be15ee1cd) by [@NickGerleman](https://github.com/NickGerleman))
- Properly fix measurement of trailing newlines ([060c594457](https://github.com/facebook/react-native/commit/060c59445740f9b92188d2193623b36c3d859ba7) by [@NickGerleman](https://github.com/NickGerleman))
- Fix crash for Modal not attached to window manager ([eaa780de1c](https://github.com/facebook/react-native/commit/eaa780de1c799bf35fded2914d27b1953b093340) by [@cipolleschi](https://github.com/cipolleschi))
- Fix NPE on ReactTextInputManager.setTextDecorationLine ([41c6ad5597](https://github.com/facebook/react-native/commit/41c6ad55978184cad1a32ec63c2d1f07e8282d5e) by [@cortinico](https://github.com/cortinico))
- BoxShadow now supports platformColor. ([4ede9205a0](https://github.com/facebook/react-native/commit/4ede9205a0559fcaf7ac58a3d70bc902eb23fcb6) by [@javache](https://github.com/javache))
- MixBlendMode now properly does state updates ([fae572d815](https://github.com/facebook/react-native/commit/fae572d815c7fb9684fc6c3b7f001de35ea8fb69) by [@jorge-cab](https://github.com/jorge-cab))
- Fix interactions between removeClippedSubviews and RTL ([513e9669e7](https://github.com/facebook/react-native/commit/513e9669e78a4bfd9b0380335c61f581343c4009) by [@NickGerleman](https://github.com/NickGerleman))
- LayoutAnimations work on full new architecture ([43af902693](https://github.com/facebook/react-native/commit/43af902693f0befde802a7f684e26b19ec7126c8) by [@javache](https://github.com/javache))
- Fix: ReactDelegate/ReactFragment crashing on New Architecture apps ([12dda31bc1](https://github.com/facebook/react-native/commit/12dda31bc12f4a04ec9df70d30328b1001bb2cec) by [@cortinico](https://github.com/cortinico))
- ReactFragment should properly instantiate ReactDelegate on Bridgeless ([7176d11ce4](https://github.com/facebook/react-native/commit/7176d11ce468ca37e9cbe8afcc1f6344c250dd0c) by [@cortinico](https://github.com/cortinico))
- Fixed text being measured incorrectly when ending with an empty line on the new architecture ([bd323929dc](https://github.com/facebook/react-native/commit/bd323929dc5be5666ee36043babec7d981a095dc) by [@j-piasecki](https://github.com/j-piasecki))
- Linear gradient with platform colors ([6866968a79](https://github.com/facebook/react-native/commit/6866968a79d44518884965959760983acdadc17c) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway))
- ARG_DISABLE_HOST_LIFECYCLE_EVENTS in ReactFragment to allow unmounting a surface without destroying ReactHost. ([40c875deca](https://github.com/facebook/react-native/commit/40c875decabaa56d6dd45ce03b22e8b3931781ac) by [@vincenzovitale](https://github.com/vincenzovitale))
- Fixed incorrect scroll event/position for scroll views when doing a smooth scroll animation. ([b4c41ec768](https://github.com/facebook/react-native/commit/b4c41ec7685da6e8ef35c41c30aa402639bc42c1) by [@rubennorte](https://github.com/rubennorte))
- Use appropriate Nullable attribute for ReactRootView field in ReactDelegate ([cbddcfc691](https://github.com/facebook/react-native/commit/cbddcfc6911101608df36f2a8d047768296c63b2) by [@rozele](https://github.com/rozele))
- Hover events were dispatched incorrectly when multiple ReactRoots were layered. ([533ef2ca37](https://github.com/facebook/react-native/commit/533ef2ca37d3b19fc909315f183e3f30dbf4b93d) by [@javache](https://github.com/javache))
- Improve text line height calculation ([65d8f66b50](https://github.com/facebook/react-native/commit/65d8f66b50471d2fb4ddd5e63e17fcc808623110) by [@mellyeliu](https://github.com/mellyeliu))
#### iOS specific
- Fix possible NSRangeException when updating typing attributes in response to new text content ([6e06a810f0](https://github.com/facebook/react-native/commit/6e06a810f0ab1002f1d10351bc878babde36b1f1) by [@NickGerleman](https://github.com/NickGerleman))
- Ensure artifacts directory exists when building Hermes from local source ([c3091ccfed](https://github.com/facebook/react-native/commit/c3091ccfed4440d7f0b906a7eb954718656b71b2) by [@kraenhansen](https://github.com/kraenhansen))
- "Reconnect DevTools" button not working sometimes ([8507204b53](https://github.com/facebook/react-native/commit/8507204b533cf87d1e4345a9c062cd10cf0022c1) by [@EdmondChuiHW](https://github.com/EdmondChuiHW))
- Fixed use of view commands from layout effects ([6f1c2a512e](https://github.com/facebook/react-native/commit/6f1c2a512e44d25edefea53e864f688018745c07) by [@sammy-SC](https://github.com/sammy-SC))
- Fix `r` & `d` not working from Metro sometimes ([9a60038a40](https://github.com/facebook/react-native/commit/9a60038a40e16925ea1adeb3e3c937c22a615485) by [@EdmondChuiHW](https://github.com/EdmondChuiHW))
- Resolve deprecated function prototype warning in RCTAppearance.h ([594c9d9a46](https://github.com/facebook/react-native/commit/594c9d9a46623016abb6bbd0d8f2982bf68bdc34) by [@eli-front](https://github.com/eli-front))
- Fixes rn-tester bundled images examples ([8cbc7c3357](https://github.com/facebook/react-native/commit/8cbc7c3357ac4043e6c423261c090a1bf656f68e) by [@zhongwuzw](https://github.com/zhongwuzw))
- Fixed `onMomentumScrollBegin` event not firing on command-driven scroll events ([5b609cca09](https://github.com/facebook/react-native/commit/5b609cca099b3b0d4fc66d4cf50f69d3c5b7fc8e) by [@Abbondanzo](https://github.com/Abbondanzo))
- Typo in spm.rb ([5e18f7f788](https://github.com/facebook/react-native/commit/5e18f7f788ccbea60e96b8e7deab29d423ccf1a6) by [@okwasniewski](https://github.com/okwasniewski))
- Add png extension only if file exist when load local image ([44f2a08371](https://github.com/facebook/react-native/commit/44f2a083716205b7560bef2f09d25830e29cd0c5) by [@zhongwuzw](https://github.com/zhongwuzw))
- FIxes CornerRadiiAreEqualAndSymmetrical error when check topLeftHorizontal == topLeftVertical ([af384a914a](https://github.com/facebook/react-native/commit/af384a914a4e9ef6a5d25b00bc14b0483e5af879) by [@zhongwuzw](https://github.com/zhongwuzw))
- Fix numerous class interfaces having incorrect designated initializer patterns ([b98846c2e3](https://github.com/facebook/react-native/commit/b98846c2e37c3ec895536ab942978d7701f51a5e) by Nolan O'Brien)
- AutomaticallyAdjustKeyboardInsets not shifting scrollview content ([2d9933e616](https://github.com/facebook/react-native/commit/2d9933e616c3efe57ed0ca141277638182a69d9c) by [@zhongwuzw](https://github.com/zhongwuzw))
- Fix launching App Clips with nullish URLs. ([043e2fe14a](https://github.com/facebook/react-native/commit/043e2fe14a6f13885a552211f17d61292001fa76) by [@EvanBacon](https://github.com/EvanBacon))
- Fixes scrollIndicatorInsets not work in old arch ([c1178ac208](https://github.com/facebook/react-native/commit/c1178ac2085e073afb07453eefc9095a1f5d530f) by [@zhongwuzw](https://github.com/zhongwuzw))
- Silenced 'set but unused variable' warning. ([f7b28e86aa](https://github.com/facebook/react-native/commit/f7b28e86aaded58f76978179d8d83f11e913b026) by [@nlutsenko](https://github.com/nlutsenko))
- Fixed crash on promise rejection handler in iOS 18. ([26d8d490e4](https://github.com/facebook/react-native/commit/26d8d490e47bd3fa46dc4a3b8e66e9ec35c15cf7) by David Rickard)
- Fixed scroll view ([ab8f3ff3e9](https://github.com/facebook/react-native/commit/ab8f3ff3e9e6445fa9961467e965792908d4c2bd) by [@coado](https://github.com/coado))
- Fixes missing char mode of linebreakmode ([77889afa1c](https://github.com/facebook/react-native/commit/77889afa1c9d0bdb966102860a5d1d1d91187ae8) by [@zhongwuzw](https://github.com/zhongwuzw))
- Removed usage of set but unused variable. ([d386dfc804](https://github.com/facebook/react-native/commit/d386dfc804842ed36565966da5aed15d9df7960e) by [@nlutsenko](https://github.com/nlutsenko))
- Cast the UIScene to UIWindowScene only if the scene respond to the selector ([fdee0ebbcb](https://github.com/facebook/react-native/commit/fdee0ebbcb88f40c23b92b07792fbb9d1041c546) by [@cipolleschi](https://github.com/cipolleschi))
- Move RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED to const ([a1ec345e2a](https://github.com/facebook/react-native/commit/a1ec345e2a2cdb4ccf255293616ed5e90f519e40) by [@okwasniewski](https://github.com/okwasniewski))
- Fixes the exported synchronous method not being called on the method queue when it's the main queue ([8bfd7e1039](https://github.com/facebook/react-native/commit/8bfd7e10393e649554c7246df430019c4f78d5e0) by [@zhongwuzw](https://github.com/zhongwuzw))
- Make sure that the Increment and Decrement accessibility actions works on iOS ([303e0ed764](https://github.com/facebook/react-native/commit/303e0ed7641409acf2d852c077f6be426afd7a0c) by [@cipolleschi](https://github.com/cipolleschi))
- Subscribe to orientation changes in RCTUIManager only on iOS ([2f5adc3874](https://github.com/facebook/react-native/commit/2f5adc3874bcdfc8d7d2c3cd5293eefec63a91f8) by [@okwasniewski](https://github.com/okwasniewski))
- Fix ActionSheetIOS crash `attempt to insert nil object from objects` ([bebd6531b5](https://github.com/facebook/react-native/commit/bebd6531b5f4ef0300aa5a4b6f9d23e60b57a25e) by [@RodolfoGS](https://github.com/RodolfoGS))
- Allow pods mixte type settings on post-install ([1e59f2e3f8](https://github.com/facebook/react-native/commit/1e59f2e3f8f0ab3ee4173bddaa089bbecf61d1eb) by [@MasGaNo](https://github.com/MasGaNo))
- Fallback to old resolve mechanism when node require fails to resolve react native path ([3cbaddbc16](https://github.com/facebook/react-native/commit/3cbaddbc164b9dc326b2a7ddc0b35ce885bc7d9d) by [@okwasniewski](https://github.com/okwasniewski))
- Fixed warnings when validating SVC ([de39a204c3](https://github.com/facebook/react-native/commit/de39a204c3588a3c02dc2e72464174c75b3a6749) by [@cipolleschi](https://github.com/cipolleschi))
- Solved SVC warnings for RNTester ([fad4a0783b](https://github.com/facebook/react-native/commit/fad4a0783b0a0478c147d9bde2ef9ab082a08297) by [@cipolleschi](https://github.com/cipolleschi))
- Don't reference PrivacyInfo.xcprivacy twice for new projects ([cadd41b1a2](https://github.com/facebook/react-native/commit/cadd41b1a2e16b1c77a8d3022f4ccbdbd5ea295f) by [@okwasniewski](https://github.com/okwasniewski))
## v0.76.3
### Fixed
#### Android specific
- Look for sdkmanager.bat ([6460d2b3e7](https://github.com/facebook/react-native/commit/6460d2b3e74c3a6e4075e9f12304c16427c3b1b2) by [@blakef](https://github.com/blakef))
- CMake Windows path normalization ([9946838bedd](https://github.com/facebook/react-native/commit/9946838beddac549053a3ba3eb3b1b49c22a3fd9) by [@blakef](https://github.com/blakef))
- Fix build failure on windows in android ([08b83005481](https://github.com/facebook/react-native/commit/08b830054812f4011becbbacdf1525701225df39) by [@FouadMagdy01](https://github.com/FouadMagdy01))
## v0.76.2
### Added
+1 -1
View File
@@ -87,7 +87,7 @@ The full documentation for React Native can be found on our [website][docs].
The React Native documentation discusses components, APIs, and topics that are specific to React Native. For further documentation on the React API that is shared between React Native and React DOM, refer to the [React documentation][r-docs].
The source for the React Native documentation and website is hosted on a separate repository, [**@facebook/react-native-website**][repo-website].
The source for the React Native documentation and website is hosted on a separate repo, [**@facebook/react-native-website**][repo-website].
[docs]: https://reactnative.dev/docs/getting-started
[r-docs]: https://react.dev/learn
+8 -12
View File
@@ -17,10 +17,6 @@ const rnTesterConfig = getDefaultConfig(
path.resolve('../../../packages/rn-tester'),
);
const JS_DIR = process.env.JS_DIR
? path.resolve(process.cwd(), process.env.JS_DIR)
: null;
const config = {
projectRoot: path.resolve(__dirname, '../../..'),
reporter: {
@@ -28,10 +24,10 @@ const config = {
},
resolver: {
blockList: /\/RendererProxy\.fb\.js$/, // Disable dependency injection for the renderer
disableHierarchicalLookup: !!JS_DIR,
disableHierarchicalLookup: !!process.env.JS_DIR,
sourceExts: ['fb.js', ...rnTesterConfig.resolver.sourceExts],
nodeModulesPaths: JS_DIR
? [path.join(JS_DIR, 'public', 'node_modules')]
nodeModulesPaths: process.env.JS_DIR
? [path.join(process.env.JS_DIR, 'public', 'node_modules')]
: [],
hasteImplModulePath: path.resolve(__dirname, 'hasteImpl.js'),
},
@@ -40,12 +36,12 @@ const config = {
// using babel-register.
babelTransformerPath: path.resolve(__dirname, 'metro-babel-transformer.js'),
},
watchFolders: JS_DIR
watchFolders: process.env.JS_DIR
? [
path.join(JS_DIR, 'RKJSModules', 'vendor', 'react'),
path.join(JS_DIR, 'tools', 'metro'),
path.join(JS_DIR, 'node_modules'),
path.join(JS_DIR, 'public', 'node_modules'),
path.join(process.env.JS_DIR, 'RKJSModules', 'vendor', 'react'),
path.join(process.env.JS_DIR, 'tools', 'metro'),
path.join(process.env.JS_DIR, 'node_modules'),
path.join(process.env.JS_DIR, 'public', 'node_modules'),
]
: [],
};
+21 -57
View File
@@ -175,38 +175,6 @@ function createMockFunction<TArgs: $ReadOnlyArray<mixed>, TReturn>(
// flowlint unsafe-getters-setters:off
class ErrorWithCustomBlame extends Error {
// Initially 5 to ignore all the frames from Babel helpers to instantiate this
// custom error class.
#ignoredFrameCount: number = 5;
#cachedProcessedStack: ?string;
blameToPreviousFrame(): this {
this.#ignoredFrameCount++;
return this;
}
get stack(): string {
if (this.#cachedProcessedStack == null) {
const originalStack = super.stack;
if (originalStack == null) {
this.#cachedProcessedStack = originalStack;
} else {
const lines = originalStack.split('\n');
lines.splice(1, this.#ignoredFrameCount);
this.#cachedProcessedStack = lines.join('\n');
}
}
return this.#cachedProcessedStack;
}
set stack(value: string) {
// no-op
}
}
class Expect {
#received: mixed;
#isNot: boolean = false;
@@ -223,27 +191,27 @@ class Expect {
toEqual(expected: mixed): void {
const pass = deepEqual(this.#received, expected, {strict: true});
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
throw new Error(
`Expected${this.#maybeNotLabel()} to equal ${String(expected)} but received ${String(this.#received)}.`,
).blameToPreviousFrame();
);
}
}
toBe(expected: mixed): void {
const pass = this.#received === expected;
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
throw new Error(
`Expected${this.#maybeNotLabel()} ${String(expected)} but received ${String(this.#received)}.`,
).blameToPreviousFrame();
);
}
}
toBeInstanceOf(expected: Class<mixed>): void {
const pass = this.#received instanceof expected;
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
throw new Error(
`expected ${String(this.#received)}${this.#maybeNotLabel()} to be an instance of ${String(expected)}`,
).blameToPreviousFrame();
);
}
}
@@ -251,26 +219,26 @@ class Expect {
const pass =
Math.abs(expected - Number(this.#received)) < Math.pow(10, -precision);
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
throw new Error(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to be close to ${expected}`,
).blameToPreviousFrame();
);
}
}
toBeNull(): void {
const pass = this.#received == null;
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
throw new Error(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to be null`,
).blameToPreviousFrame();
);
}
}
toThrow(expected?: string): void {
if (expected != null && typeof expected !== 'string') {
throw new ErrorWithCustomBlame(
throw new Error(
'toThrow() implementation only accepts strings as arguments.',
).blameToPreviousFrame();
);
}
let pass = false;
@@ -281,9 +249,9 @@ class Expect {
pass = expected != null ? error.message === expected : true;
}
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
throw new Error(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to throw`,
).blameToPreviousFrame();
);
}
}
@@ -291,9 +259,9 @@ class Expect {
const mock = this.#requireMock();
const pass = mock.calls.length > 0;
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
throw new Error(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to have been called, but it was${this.#isNot ? '' : "n't"}`,
).blameToPreviousFrame();
);
}
}
@@ -301,9 +269,9 @@ class Expect {
const mock = this.#requireMock();
const pass = mock.calls.length === times;
if (!this.#isExpectedResult(pass)) {
throw new ErrorWithCustomBlame(
throw new Error(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to have been called ${times} times, but it was called ${mock.calls.length} times`,
).blameToPreviousFrame();
);
}
}
@@ -318,11 +286,9 @@ class Expect {
#requireMock(): JestMockFn<$ReadOnlyArray<mixed>, mixed>['mock'] {
// $FlowExpectedError[incompatible-use]
if (!this.#received?.[MOCK_FN_TAG]) {
throw new ErrorWithCustomBlame(
throw new Error(
`Expected ${String(this.#received)} to be a mock function, but it wasn't`,
)
.blameToPreviousFrame()
.blameToPreviousFrame();
);
}
// $FlowExpectedError[incompatible-use]
@@ -380,9 +346,7 @@ function executeTests() {
result.status = status;
result.duration = Date.now() - start;
result.failureMessages =
status === 'failed' && error
? [error.stack ?? error.message ?? String(error)]
: [];
status === 'failed' && error ? [error.message] : [];
}
}
+1 -1
View File
@@ -77,7 +77,7 @@
"eslint-plugin-redundant-undefined": "^0.4.0",
"eslint-plugin-relay": "^1.8.3",
"flow-api-translator": "0.25.1",
"flow-bin": "^0.255.0",
"flow-bin": "^0.253.0",
"glob": "^7.1.1",
"hermes-eslint": "0.25.1",
"hermes-transform": "0.25.1",
@@ -30,6 +30,7 @@
"metro": "^0.81.0",
"metro-config": "^0.81.0",
"metro-core": "^0.81.0",
"node-fetch": "^2.2.0",
"readline": "^1.3.0",
"semver": "^7.1.3"
},
@@ -12,6 +12,7 @@
import type TerminalReporter from 'metro/src/lib/TerminalReporter';
import chalk from 'chalk';
import fetch from 'node-fetch';
type PageDescription = $ReadOnly<{
id: string,
@@ -10,6 +10,7 @@
*/
import net from 'net';
import fetch from 'node-fetch';
/**
* Determine whether we can run the dev server.
@@ -23,11 +23,10 @@ export class DebuggerAgent {
#ws: ?WebSocket;
#readyPromise: Promise<void>;
constructor(url: string, signal?: AbortSignal, hostHeader?: ?string) {
constructor(url: string, signal?: AbortSignal) {
const ws = new WebSocket(url, {
// The mock server uses a self-signed certificate.
rejectUnauthorized: false,
...(hostHeader != null ? {headers: {Host: hostHeader}} : {}),
});
this.#ws = ws;
ws.on('message', data => {
@@ -116,9 +115,8 @@ export class DebuggerMock extends DebuggerAgent {
export async function createDebuggerMock(
url: string,
signal: AbortSignal,
hostHeader?: ?string,
): Promise<DebuggerMock> {
const debuggerMock = new DebuggerMock(url, signal, hostHeader);
const debuggerMock = new DebuggerMock(url, signal);
await debuggerMock.ready();
return debuggerMock;
}
@@ -127,13 +127,11 @@ export async function createAndConnectTarget(
signal: AbortSignal,
page: PageFromDevice,
{
debuggerHostHeader = null,
deviceId = null,
deviceHostHeader = null,
host = null,
}: $ReadOnly<{
debuggerHostHeader?: ?string,
deviceId?: ?string,
deviceHostHeader?: ?string,
host?: ?string,
}> = {},
): Promise<{device: DeviceMock, debugger_: DebuggerMock}> {
let device;
@@ -144,7 +142,7 @@ export async function createAndConnectTarget(
deviceId ?? 'device' + Date.now()
}&name=foo&app=bar`,
signal,
deviceHostHeader,
host,
);
device.getPages.mockImplementation(() => [page]);
@@ -159,11 +157,7 @@ export async function createAndConnectTarget(
const [{webSocketDebuggerUrl}] = pageList;
expect(webSocketDebuggerUrl).toBeDefined();
debugger_ = await createDebuggerMock(
webSocketDebuggerUrl,
signal,
debuggerHostHeader,
);
debugger_ = await createDebuggerMock(webSocketDebuggerUrl, signal);
await until(() => expect(device.connect).toBeCalled());
} catch (e) {
device?.close();
@@ -207,7 +207,7 @@ describe.each(['HTTP', 'HTTPS'])(
vm: 'bar-vm',
},
{
deviceHostHeader: '192.168.0.123:' + serverRef.port,
host: '192.168.0.123:' + serverRef.port,
},
);
try {
@@ -240,7 +240,52 @@ describe.each(['HTTP', 'HTTPS'])(
}
});
describe.each(['10.0.2.2:8080', '[::1]', 'example.com:2000'])(
test('does not rewrite urls in Debugger.scriptParsed that match the device connection host but are not allowlisted for rewriting', async () => {
serverRef.app.use('/source-map', serveStaticJson({version: 3}));
const {device, debugger_} = await createAndConnectTarget(
serverRef,
autoCleanup.signal,
{
app: 'bar-app',
id: 'page1',
title: 'bar-title',
vm: 'bar-vm',
},
{
host: '192.168.0.123:' + serverRef.port,
},
);
try {
let fetchCalledWithURL;
fetchSpy.mockImplementationOnce(url => {
fetchCalledWithURL = url instanceof URL ? url : null;
throw new Error('Unreachable');
});
const sourceMapURL = `${protocol.toLowerCase()}://192.168.0.123:${
serverRef.port
}/source-map`;
const scriptParsedMessage = await sendFromTargetToDebugger(
device,
debugger_,
'page1',
{
method: 'Debugger.scriptParsed',
params: {
sourceMapURL,
},
},
);
expect(fetchCalledWithURL?.href).toEqual(sourceMapURL);
expect(scriptParsedMessage.params.sourceMapURL).toEqual(
`${protocol.toLowerCase()}://192.168.0.123:${serverRef.port}/source-map`,
);
} finally {
device.close();
debugger_.close();
}
});
describe.each(['10.0.2.2', '10.0.3.2', '127.0.0.1'])(
'%s aliasing to and from localhost',
sourceHost => {
test('in source map fetching during Debugger.scriptParsed', async () => {
@@ -255,7 +300,7 @@ describe.each(['HTTP', 'HTTPS'])(
vm: 'bar-vm',
},
{
deviceHostHeader: sourceHost,
host: sourceHost + ':' + serverRef.port,
},
);
try {
@@ -266,7 +311,9 @@ describe.each(['HTTP', 'HTTPS'])(
{
method: 'Debugger.scriptParsed',
params: {
sourceMapURL: `${protocol.toLowerCase()}://${sourceHost}/source-map`,
sourceMapURL: `${protocol.toLowerCase()}://${sourceHost}:${
serverRef.port
}/source-map`,
},
},
);
@@ -290,8 +337,7 @@ describe.each(['HTTP', 'HTTPS'])(
vm: 'bar-vm',
},
{
debuggerHostHeader: 'localhost:' + serverRef.port,
deviceHostHeader: sourceHost,
host: sourceHost + ':' + serverRef.port,
},
);
try {
@@ -302,7 +348,9 @@ describe.each(['HTTP', 'HTTPS'])(
{
method: 'Debugger.scriptParsed',
params: {
url: `${protocol.toLowerCase()}://${sourceHost}/some/file.js`,
url: `${protocol.toLowerCase()}://${sourceHost}:${
serverRef.port
}/some/file.js`,
},
},
);
@@ -328,7 +376,9 @@ describe.each(['HTTP', 'HTTPS'])(
},
);
expect(setBreakpointByUrlMessage.params.url).toEqual(
`${protocol.toLowerCase()}://${sourceHost}/some/file.js`,
`${protocol.toLowerCase()}://${sourceHost}:${
serverRef.port
}/some/file.js`,
);
const setBreakpointByUrlRegexMessage =
@@ -340,20 +390,9 @@ describe.each(['HTTP', 'HTTPS'])(
urlRegex: `localhost:${serverRef.port}|example.com:2000`,
},
});
// urlRegex rewriting is restricted to specific Android IPs that
// are well-known to route to the host. In this case we only
// replace hostname - longstanding behaviour.
if (sourceHost === '10.0.2.2:8080') {
expect(setBreakpointByUrlRegexMessage.params.urlRegex).toEqual(
`10\\.0\\.2\\.2:${serverRef.port}|example.com:2000`,
);
} else {
// Otherwise expect no change.
expect(setBreakpointByUrlRegexMessage.params.urlRegex).toEqual(
`localhost:${serverRef.port}|example.com:2000`,
);
}
expect(setBreakpointByUrlRegexMessage.params.urlRegex).toEqual(
`${sourceHost.replaceAll('.', '\\.')}:${serverRef.port}|example.com:2000`,
);
} finally {
device.close();
debugger_.close();
@@ -372,7 +411,7 @@ describe.each(['HTTP', 'HTTPS'])(
vm: 'bar-vm',
},
{
deviceHostHeader: sourceHost,
host: sourceHost + ':' + serverRef.port,
},
);
try {
@@ -412,7 +451,7 @@ describe.each(['HTTP', 'HTTPS'])(
vm: 'bar-vm',
},
{
deviceHostHeader: '127.0.0.1:' + serverRef.port,
host: '127.0.0.1:' + serverRef.port,
},
);
try {
@@ -11,7 +11,7 @@
import type {CreateCustomMessageHandlerFn} from './inspector-proxy/CustomMessageHandler';
import type {BrowserLauncher} from './types/BrowserLauncher';
import type {EventReporter, ReportableEvent} from './types/EventReporter';
import type {EventReporter} from './types/EventReporter';
import type {Experiments, ExperimentsConfig} from './types/Experiments';
import type {Logger} from './types/Logger';
import type {NextHandleFunction} from 'connect';
@@ -81,15 +81,11 @@ export default function createDevMiddleware({
unstable_customInspectorMessageHandler,
}: Options): DevMiddlewareAPI {
const experiments = getExperiments(experimentConfig);
const eventReporter = createWrappedEventReporter(
unstable_eventReporter,
logger,
);
const inspectorProxy = new InspectorProxy(
projectRoot,
serverBaseUrl,
eventReporter,
unstable_eventReporter,
experiments,
unstable_customInspectorMessageHandler,
);
@@ -101,7 +97,7 @@ export default function createDevMiddleware({
serverBaseUrl,
inspectorProxy,
browserLauncher: unstable_browserLauncher,
eventReporter,
eventReporter: unstable_eventReporter,
experiments,
logger,
}),
@@ -133,26 +129,3 @@ function getExperiments(config: ExperimentsConfig): Experiments {
enableNetworkInspector: config.enableNetworkInspector ?? false,
};
}
/**
* Creates a wrapped EventReporter that locally intercepts events to
* log to the terminal.
*/
function createWrappedEventReporter(
reporter: ?EventReporter,
logger: ?Logger,
): EventReporter {
return {
logEvent(event: ReportableEvent) {
switch (event.type) {
case 'profiling_target_registered':
logger?.info(
`Profiling build target "${event.appId}" registered for debugging`,
);
break;
}
reporter?.logEvent(event);
},
};
}
@@ -37,6 +37,22 @@ const debug = require('debug')('Metro:InspectorProxy');
const PAGES_POLLING_INTERVAL = 1000;
// Replace hosts appearing in the `url` and `sourceMapURL` fields of
// `Debugger.scriptParsed`, and back again in messages from the debugger,
// to account for device/debugger/proxy running on different networks.
const REWRITE_HOSTS_TO_LOCALHOST: $ReadOnlySet<string> = new Set([
// A device may retrieve a bundle through 127.0.0.1 via a (SSH) tunnel, but
// the (remote) Metro server may be on a host without an IPv4 loopback, so
// 127.0.0.1 may not be addressible locally for (e.g., for source map
// fetching). Replacing with the more general 'localhost' should always be
// safe while also more compatible with IPv6-only setups.
'127.0.0.1',
// Android's stock emulator and other emulators such as genymotion use a
// standard localhost alias.
'10.0.2.2',
'10.0.3.2',
]);
// Prefix for script URLs that are alphanumeric IDs. See comment in #processMessageFromDeviceLegacy method for
// more details.
const FILE_PREFIX = 'file://';
@@ -44,6 +60,10 @@ const FILE_PREFIX = 'file://';
type DebuggerConnection = {
// Debugger web socket connection
socket: WS,
// If we replaced a device-relative origin (like 'http://10.0.2.2:8082') with
// debugger-relative, we store the original address to reverse the operation
// on messages back from the frontend, such as setting breakpoints.
originalSourceURLOrigin?: string,
prependedFilePrefix: boolean,
pageId: string,
userAgent: string | null,
@@ -63,7 +83,6 @@ export type DeviceOptions = $ReadOnly<{
createMessageMiddleware: ?CreateCustomMessageHandlerFn,
deviceRelativeBaseUrl: URL,
serverRelativeBaseUrl: URL,
isProfilingBuild: boolean,
}>;
/**
@@ -141,7 +160,6 @@ export default class Device {
createMessageMiddleware,
serverRelativeBaseUrl,
deviceRelativeBaseUrl,
isProfilingBuild,
}: DeviceOptions) {
this.#id = id;
this.#name = name;
@@ -159,10 +177,6 @@ export default class Device {
: null;
this.#createCustomMessageHandler = createMessageMiddleware;
if (isProfilingBuild) {
this.#deviceEventReporter?.logProfilingTargetRegistered();
}
// $FlowFixMe[incompatible-call]
this.#deviceSocket.on('message', (message: string) => {
this.#messageFromDeviceQueue = this.#messageFromDeviceQueue
@@ -661,54 +675,6 @@ export default class Device {
}
}
/**
* Given a URL from the debugger frontend, returns the equivalent URL
* reachable from the device.
*/
#debuggerRelativeToDeviceRelativeUrl(
debuggerRelativeUrl: URL,
{debuggerRelativeBaseUrl}: DebuggerConnection,
): URL {
const deviceRelativeUrl = new URL(debuggerRelativeUrl.href);
if (debuggerRelativeUrl.origin === debuggerRelativeBaseUrl.origin) {
deviceRelativeUrl.hostname = this.#deviceRelativeBaseUrl.hostname;
deviceRelativeUrl.port = this.#deviceRelativeBaseUrl.port;
deviceRelativeUrl.protocol = this.#deviceRelativeBaseUrl.protocol;
}
return deviceRelativeUrl;
}
/**
* Given a URL from the device, returns the equivalent URL reachable from
* the debugger frontend.
*/
#deviceRelativeUrlToDebuggerRelativeUrl(
deviceRelativeUrl: URL,
{debuggerRelativeBaseUrl}: DebuggerConnection,
): URL {
const debuggerRelativeUrl = new URL(deviceRelativeUrl.href);
if (deviceRelativeUrl.origin === this.#deviceRelativeBaseUrl.origin) {
debuggerRelativeUrl.hostname = debuggerRelativeBaseUrl.hostname;
debuggerRelativeUrl.port = debuggerRelativeBaseUrl.port;
debuggerRelativeUrl.protocol = debuggerRelativeUrl.protocol;
}
return debuggerRelativeUrl;
}
/**
* Given a URL from the device, returns the equivalent URL reachable from
* this proxy.
*/
#deviceRelativeUrlToServerRelativeUrl(deviceRelativeUrl: URL): URL {
const debuggerRelativeUrl = new URL(deviceRelativeUrl.href);
if (deviceRelativeUrl.origin === this.#deviceRelativeBaseUrl.origin) {
debuggerRelativeUrl.hostname = this.#serverRelativeBaseUrl.hostname;
debuggerRelativeUrl.port = this.#serverRelativeBaseUrl.port;
debuggerRelativeUrl.protocol = this.#serverRelativeBaseUrl.protocol;
}
return debuggerRelativeUrl;
}
// Allows to make changes in incoming message from device.
async #processMessageFromDeviceLegacy(
payload: CDPServerMessage,
@@ -729,14 +695,36 @@ export default class Device {
const params = payload.params;
if ('sourceMapURL' in params) {
const sourceMapURL = this.#tryParseHTTPURL(params.sourceMapURL);
if (sourceMapURL) {
// This URL will be used to fetch from the server, and will be
// mutated if necessary from device-relative to server-relative.
// This is not exposed to the debugger.
const serverRelativeUrl = new URL(sourceMapURL.href);
// Rewrite device-relative URLs to de debugger-relative URLs for the
// frontend.
payload.params.sourceMapURL =
this.#deviceRelativeUrlToDebuggerRelativeUrl(
sourceMapURL,
debuggerInfo,
).href;
if (
// sourceMapURL is a device-relative url to the server.
// May or may not be reachable from the frontend.
sourceMapURL.origin === this.#deviceRelativeBaseUrl.origin &&
// For a specific set of IPs (eg 10.0.2.2) it's relatively safe to
// assume the frontend can reach the server on localhost.
// TODO: Fix the assumption that localhost:[same port] is correct
// and remove this check.
REWRITE_HOSTS_TO_LOCALHOST.has(this.#deviceRelativeBaseUrl.hostname)
) {
const debuggerRelativeURL = new URL(sourceMapURL.href);
debuggerRelativeURL.host =
debuggerInfo.debuggerRelativeBaseUrl.host;
debuggerRelativeURL.protocol =
debuggerInfo.debuggerRelativeBaseUrl.protocol;
serverRelativeUrl.host = this.#serverRelativeBaseUrl.host;
serverRelativeUrl.protocol = this.#serverRelativeBaseUrl.protocol;
debuggerInfo.originalSourceURLOrigin =
this.#deviceRelativeBaseUrl.origin;
payload.params.sourceMapURL = debuggerRelativeURL.href;
}
// Some debug clients do not support fetching HTTP URLs. If the
// message headed to the debug client identifies the source map with
@@ -744,9 +732,7 @@ export default class Device {
// Data URL (which is more widely supported) before passing the
// message to the debug client.
try {
const sourceMap = await this.#fetchText(
this.#deviceRelativeUrlToServerRelativeUrl(sourceMapURL),
);
const sourceMap = await this.#fetchText(serverRelativeUrl);
payload.params.sourceMapURL =
'data:application/json;charset=utf-8;base64,' +
Buffer.from(sourceMap).toString('base64');
@@ -760,17 +746,31 @@ export default class Device {
if ('url' in params) {
let serverRelativeUrl = params.url;
const parsedUrl = this.#tryParseHTTPURL(params.url);
if (parsedUrl) {
// Rewrite device-relative URLs pointing to the server so that they're
// reachable from the frontend.
payload.params.url = this.#deviceRelativeUrlToDebuggerRelativeUrl(
parsedUrl,
debuggerInfo,
).href;
// Rewrite device-relative URLs pointing to the server so that they're
// reachable from the frontend.
if (
parsedUrl &&
// url is a device-relative url to the server.
// May or may not be reachable from the frontend.
parsedUrl.origin === this.#deviceRelativeBaseUrl.origin &&
// For a specific set of IPs (eg 10.0.2.2) it's relatively safe to
// assume the frontend can reach the server on localhost.
// TODO: Fix the assumption that localhost:[same port] is correct and
// remove this check.
REWRITE_HOSTS_TO_LOCALHOST.has(this.#deviceRelativeBaseUrl.hostname)
) {
// URL is device-relative and points to the host - rewrite it to
// use localhost.
parsedUrl.host = debuggerInfo.debuggerRelativeBaseUrl.host;
parsedUrl.protocol = debuggerInfo.debuggerRelativeBaseUrl.protocol;
payload.params.url = parsedUrl.href;
debuggerInfo.originalSourceURLOrigin =
this.#deviceRelativeBaseUrl.origin;
// Determine the server-relative URL.
serverRelativeUrl =
this.#deviceRelativeUrlToServerRelativeUrl(parsedUrl).href;
parsedUrl.host = this.#serverRelativeBaseUrl.host;
parsedUrl.protocol = this.#serverRelativeBaseUrl.protocol;
serverRelativeUrl = parsedUrl.href;
}
// Chrome doesn't download source maps if URL param is not a valid
@@ -883,23 +883,28 @@ export default class Device {
debuggerInfo: DebuggerConnection,
): CDPRequest<'Debugger.setBreakpointByUrl'> {
// If we replaced Android emulator's address to localhost we need to change it back.
const {debuggerRelativeBaseUrl, prependedFilePrefix} = debuggerInfo;
const {
debuggerRelativeBaseUrl,
originalSourceURLOrigin,
prependedFilePrefix,
} = debuggerInfo;
const processedReq = {...req, params: {...req.params}};
if (processedReq.params.url != null) {
const originalUrlParam = processedReq.params.url;
const httpUrl = this.#tryParseHTTPURL(originalUrlParam);
if (httpUrl) {
processedReq.params.url = this.#debuggerRelativeToDeviceRelativeUrl(
httpUrl,
debuggerInfo,
).href;
} else if (
originalUrlParam.startsWith(FILE_PREFIX) &&
if (originalSourceURLOrigin != null && processedReq.params.url != null) {
processedReq.params.url = processedReq.params.url.replace(
debuggerRelativeBaseUrl.origin,
originalSourceURLOrigin,
);
if (
processedReq.params.url &&
processedReq.params.url.startsWith(FILE_PREFIX) &&
prependedFilePrefix
) {
// Remove fake URL prefix if we modified URL in #processMessageFromDeviceLegacy.
processedReq.params.url = originalUrlParam.slice(FILE_PREFIX.length);
// $FlowFixMe[incompatible-use]
processedReq.params.url = processedReq.params.url.slice(
FILE_PREFIX.length,
);
}
}
@@ -914,11 +919,8 @@ export default class Device {
// `file://` source URLs. It can be removed when we drop support for
// legacy targets, if not sooner.
if (
// Android's stock emulator and other emulators such as genymotion use a
// standard localhost alias.
new Set(['10.0.2.2', '10.0.3.2']).has(
this.#deviceRelativeBaseUrl.hostname,
) &&
REWRITE_HOSTS_TO_LOCALHOST.has(this.#deviceRelativeBaseUrl.hostname) &&
this.#deviceRelativeBaseUrl.port === debuggerRelativeBaseUrl.port &&
debuggerRelativeBaseUrl.hostname === 'localhost' &&
processedReq.params.urlRegex != null
) {
@@ -145,17 +145,6 @@ class DeviceEventReporter {
});
}
logProfilingTargetRegistered() {
this.#eventReporter.logEvent({
type: 'profiling_target_registered',
status: 'success',
appId: this.#metadata.appId,
deviceName: this.#metadata.deviceName,
deviceId: this.#metadata.deviceId,
pageId: null,
});
}
logConnection(
connectedEntity: 'debugger',
metadata: $ReadOnly<{
@@ -225,7 +225,6 @@ export default class InspectorProxy implements InspectorProxyQueries {
const deviceId = query.device || fallbackDeviceId;
const deviceName = query.name || 'Unknown';
const appName = query.app || 'Unknown';
const isProfilingBuild = query.profiling === 'true';
const deviceRelativeBaseUrl =
getBaseUrlFromRequest(req) ?? this.#serverBaseUrl;
@@ -243,7 +242,6 @@ export default class InspectorProxy implements InspectorProxyQueries {
createMessageMiddleware: this.#customMessageHandler,
deviceRelativeBaseUrl,
serverRelativeBaseUrl: this.#serverBaseUrl,
isProfilingBuild,
};
if (oldDevice) {
@@ -77,11 +77,6 @@ export type ReportableEvent =
| 'PROTOCOL_ERROR',
>,
}
| {
type: 'profiling_target_registered',
status: 'success',
...DebuggerSessionIDs,
}
| {
type: 'proxy_error',
status: 'error',
@@ -39,7 +39,7 @@ abstract class BuildCodegenCLITask : Exec() {
}
override fun exec() {
val logfile = "${project.layout.buildDirectory.getAsFile().get()}/build-cli.log"
val logfile = "${project.layout.buildDirectory}/build-cli.log"
File(logfile).apply {
parentFile.mkdirs()
if (exists()) {
@@ -2673,7 +2673,7 @@ const UNION_MODULE: SchemaType = {
},
};
const STRING_LITERALS: SchemaType = {
const STRING_LITERALS = {
modules: {
NativeSampleTurboModule: {
type: 'NativeModule',
@@ -116,8 +116,6 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
};
_onLayout = async (event: ViewLayoutEvent) => {
event.persist();
const oldFrame = this._frame;
this._frame = event.nativeEvent.layout;
if (!this._initialFrameHeight) {
@@ -567,6 +567,9 @@ export type ViewProps = $ReadOnly<{|
* optimization. Set this property to `false` to disable this optimization and
* ensure that this `View` exists in the native view hierarchy.
*
* @platform android
* In Fabric, this prop is used in ios as well.
*
* See https://reactnative.dev/docs/view#collapsable
*/
collapsable?: ?boolean,
@@ -121,12 +121,6 @@ function reportException(
const NativeExceptionsManager =
require('./NativeExceptionsManager').default;
if (NativeExceptionsManager) {
if (isFatal) {
if (global.RN$hasHandledFatalException?.()) {
return;
}
global.RN$notifyOfFatalException?.();
}
NativeExceptionsManager.reportException(data);
}
}
@@ -121,7 +121,7 @@ const Presets = {
'opacity',
): LayoutAnimationConfig),
linear: (create(500, 'linear', 'opacity'): LayoutAnimationConfig),
spring: ({
spring: {
duration: 700,
create: {
type: 'linear',
@@ -135,7 +135,7 @@ const Presets = {
type: 'linear',
property: 'opacity',
},
}: LayoutAnimationConfig),
},
};
/**
@@ -1,39 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
* @oncall react_native
*/
import useColorScheme from '../useColorScheme';
describe('useColorScheme', () => {
it('should return a mocked light theme by default', () => {
expect(jest.isMockFunction(useColorScheme)).toBe(true);
expect(useColorScheme()).toBe('light');
});
it('should have console.error when not using mock', () => {
const useColorSchemeActual = jest.requireActual<{
default: typeof useColorScheme,
}>('../useColorScheme').default;
const spy = jest.spyOn(console, 'error').mockImplementationOnce(() => {
// Simulate LogBox console.error() call to throw an error and stop the further execution
throw new Error('console.error() was called');
});
expect(() => {
useColorSchemeActual();
}).toThrow();
expect(spy).toHaveBeenCalledWith(
expect.stringMatching(
/Invalid hook call. Hooks can only be called inside of the body of a function component./,
),
);
});
});
@@ -5609,7 +5609,12 @@ declare function create(
declare const Presets: {
easeInEaseOut: LayoutAnimationConfig,
linear: LayoutAnimationConfig,
spring: LayoutAnimationConfig,
spring: {
duration: 700,
create: { type: \\"linear\\", property: \\"opacity\\" },
update: { type: \\"spring\\", springDamping: 0.4 },
delete: { type: \\"linear\\", property: \\"opacity\\" },
},
};
declare const LayoutAnimation: {
configureNext: configureNext,
@@ -67,52 +67,28 @@
* ScrollView, we force it to be centered, but when you zoom or the content otherwise
* becomes larger than the ScrollView, there is no padding around the content but it
* can still fill the whole view.
* This implementation is based on https://petersteinberger.com/blog/2013/how-to-center-uiscrollview/.
*/
- (void)centerContentIfNeeded
{
if (!_centerContent) {
return;
}
CGSize contentSize = self.contentSize;
CGSize boundsSize = self.bounds.size;
if (CGSizeEqualToSize(contentSize, CGSizeZero) || CGSizeEqualToSize(boundsSize, CGSizeZero)) {
return;
}
CGFloat top = 0, left = 0;
if (contentSize.width < boundsSize.width) {
left = (boundsSize.width - contentSize.width) * 0.5f;
}
if (contentSize.height < boundsSize.height) {
top = (boundsSize.height - contentSize.height) * 0.5f;
}
self.contentInset = UIEdgeInsetsMake(top, left, top, left);
}
- (void)setContentOffset:(CGPoint)contentOffset
{
if (_isSetContentOffsetDisabled) {
return;
}
if (_centerContent && !CGSizeEqualToSize(self.contentSize, CGSizeZero)) {
CGSize scrollViewSize = self.bounds.size;
if (self.contentSize.width <= scrollViewSize.width) {
contentOffset.x = -(scrollViewSize.width - self.contentSize.width) / 2.0;
}
if (self.contentSize.height <= scrollViewSize.height) {
contentOffset.y = -(scrollViewSize.height - self.contentSize.height) / 2.0;
}
}
super.contentOffset = CGPointMake(
RCTSanitizeNaNValue(contentOffset.x, @"scrollView.contentOffset.x"),
RCTSanitizeNaNValue(contentOffset.y, @"scrollView.contentOffset.y"));
}
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
[self centerContentIfNeeded];
}
- (void)didAddSubview:(UIView *)subview
{
[super didAddSubview:subview];
[self centerContentIfNeeded];
}
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
if ([_overridingDelegate respondsToSelector:@selector(touchesShouldCancelInContentView:)]) {
@@ -282,11 +258,6 @@
}
}
- (void)scrollViewDidZoom:(__unused UIScrollView *)scrollView
{
[self centerContentIfNeeded];
}
#pragma mark -
- (BOOL)isHorizontal:(UIScrollView *)scrollView
@@ -121,8 +121,8 @@ using namespace facebook::react;
auto &props = *sharedProps;
props.layoutConstraints = LayoutConstraints{{0, 0}, {500, 500}};
auto &yogaStyle = props.yogaStyle;
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(200));
return sharedProps;
})
.children({
@@ -136,8 +136,8 @@ using namespace facebook::react;
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(0));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(200));
return sharedProps;
})
.children({
@@ -216,8 +216,8 @@ using namespace facebook::react;
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(30));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(50));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(50));
return sharedProps;
})
.children({
@@ -260,8 +260,8 @@ using namespace facebook::react;
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(90));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(50));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(50));
return sharedProps;
})
.children({
@@ -418,8 +418,8 @@ static ParagraphShadowNode::ConcreteState::Shared stateWithShadowNode(
auto &props = *sharedProps;
props.layoutConstraints = LayoutConstraints{{0, 0}, {500, 500}};
auto &yogaStyle = props.yogaStyle;
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(200));
return sharedProps;
})
.children({
@@ -434,8 +434,8 @@ static ParagraphShadowNode::ConcreteState::Shared stateWithShadowNode(
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(90));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(20));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(20));
return sharedProps;
})
.children({
@@ -87,6 +87,9 @@ CGFloat RCTCoreGraphicsFloatFromYogaValue(YGValue value, CGFloat baseFloatValue)
return RCTCoreGraphicsFloatFromYogaFloat(value.value) * baseFloatValue;
case YGUnitAuto:
case YGUnitUndefined:
case YGUnitMaxContent:
case YGUnitFitContent:
case YGUnitStretch:
return baseFloatValue;
}
}
@@ -63,6 +63,9 @@ typedef NS_ENUM(unsigned int, meta_prop_t) {
#define RCT_SET_YGVALUE(ygvalue, setter, ...) \
switch (ygvalue.unit) { \
case YGUnitAuto: \
case YGUnitMaxContent: \
case YGUnitFitContent: \
case YGUnitStretch: \
case YGUnitUndefined: \
setter(__VA_ARGS__, YGUndefined); \
break; \
@@ -88,6 +91,35 @@ typedef NS_ENUM(unsigned int, meta_prop_t) {
case YGUnitPercent: \
setter##Percent(__VA_ARGS__, ygvalue.value); \
break; \
case YGUnitMaxContent: \
case YGUnitFitContent: \
case YGUnitStretch: \
break; \
}
#define RCT_SET_YGVALUE_AUTO_INTRINSIC(ygvalue, setter, ...) \
switch (ygvalue.unit) { \
case YGUnitAuto: \
setter##Auto(__VA_ARGS__); \
break; \
case YGUnitMaxContent: \
setter##MaxContent(__VA_ARGS__); \
break; \
case YGUnitFitContent: \
setter##FitContent(__VA_ARGS__); \
break; \
case YGUnitStretch: \
setter##Stretch(__VA_ARGS__); \
break; \
case YGUnitUndefined: \
setter(__VA_ARGS__, YGUndefined); \
break; \
case YGUnitPoint: \
setter(__VA_ARGS__, ygvalue.value); \
break; \
case YGUnitPercent: \
setter##Percent(__VA_ARGS__, ygvalue.value); \
break; \
}
static void RCTProcessMetaPropsPadding(const YGValue metaProps[META_PROP_COUNT], YGNodeRef node)
@@ -483,14 +515,14 @@ RCT_BORDER_PROPERTY(Start, START)
RCT_BORDER_PROPERTY(End, END)
// Dimensions
#define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp) \
-(void)set##setProp : (YGValue)value \
{ \
RCT_SET_YGVALUE_AUTO(value, YGNodeStyleSet##cssProp, _yogaNode); \
} \
-(YGValue)getProp \
{ \
return YGNodeStyleGet##cssProp(_yogaNode); \
#define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp) \
-(void)set##setProp : (YGValue)value \
{ \
RCT_SET_YGVALUE_AUTO_INTRINSIC(value, YGNodeStyleSet##cssProp, _yogaNode); \
} \
-(YGValue)getProp \
{ \
return YGNodeStyleGet##cssProp(_yogaNode); \
}
#define RCT_MIN_MAX_DIMENSION_PROPERTY(setProp, getProp, cssProp) \
@@ -634,7 +666,7 @@ RCTShadowViewMeasure(YGNodeConstRef node, float width, YGMeasureMode widthMode,
- (void)setFlexBasis:(YGValue)value
{
RCT_SET_YGVALUE_AUTO(value, YGNodeStyleSetFlexBasis, _yogaNode);
RCT_SET_YGVALUE_AUTO_INTRINSIC(value, YGNodeStyleSetFlexBasis, _yogaNode);
}
- (YGValue)flexBasis
@@ -159,8 +159,26 @@
return !shouldDisableScrollInteraction;
}
/*
* Automatically centers the content such that if the content is smaller than the
* ScrollView, we force it to be centered, but when you zoom or the content otherwise
* becomes larger than the ScrollView, there is no padding around the content but it
* can still fill the whole view.
*/
- (void)setContentOffset:(CGPoint)contentOffset
{
UIView *contentView = [self contentView];
if (contentView && _centerContent && !CGSizeEqualToSize(contentView.frame.size, CGSizeZero)) {
CGSize subviewSize = contentView.frame.size;
CGSize scrollViewSize = self.bounds.size;
if (subviewSize.width <= scrollViewSize.width) {
contentOffset.x = -(scrollViewSize.width - subviewSize.width) / 2.0;
}
if (subviewSize.height <= scrollViewSize.height) {
contentOffset.y = -(scrollViewSize.height - subviewSize.height) / 2.0;
}
}
super.contentOffset = CGPointMake(
RCTSanitizeNaNValue(contentOffset.x, @"scrollView.contentOffset.x"),
RCTSanitizeNaNValue(contentOffset.y, @"scrollView.contentOffset.y"));
@@ -415,12 +433,6 @@ static inline void RCTApplyTransformationAccordingLayoutDirection(
// Does nothing
}
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
[self centerContentIfNeeded];
}
- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
{
[super insertReactSubview:view atIndex:atIndex];
@@ -438,8 +450,6 @@ static inline void RCTApplyTransformationAccordingLayoutDirection(
RCTApplyTransformationAccordingLayoutDirection(_contentView, self.reactLayoutDirection);
[_scrollView addSubview:view];
}
[self centerContentIfNeeded];
}
- (void)removeReactSubview:(UIView *)subview
@@ -648,45 +658,9 @@ static inline void RCTApplyTransformationAccordingLayoutDirection(
}
RCT_SCROLL_EVENT_HANDLER(scrollViewWillBeginDecelerating, onMomentumScrollBegin)
RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, onScroll)
RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
[self centerContentIfNeeded];
RCT_SEND_SCROLL_EVENT(onScroll, nil);
RCT_FORWARD_SCROLL_EVENT(scrollViewDidZoom : scrollView);
}
/*
* Automatically centers the content such that if the content is smaller than the
* ScrollView, we force it to be centered, but when you zoom or the content otherwise
* becomes larger than the ScrollView, there is no padding around the content but it
* can still fill the whole view.
* This implementation is based on https://petersteinberger.com/blog/2013/how-to-center-uiscrollview/.
*/
- (void)centerContentIfNeeded
{
if (!_scrollView.centerContent) {
return;
}
CGSize contentSize = self.contentSize;
CGSize boundsSize = self.bounds.size;
if (CGSizeEqualToSize(contentSize, CGSizeZero) || CGSizeEqualToSize(boundsSize, CGSizeZero)) {
return;
}
CGFloat top = 0, left = 0;
if (contentSize.width < boundsSize.width) {
left = (boundsSize.width - contentSize.width) * 0.5f;
}
if (contentSize.height < boundsSize.height) {
top = (boundsSize.height - contentSize.height) * 0.5f;
}
_scrollView.contentInset = UIEdgeInsetsMake(top, left, top, left);
}
- (void)addScrollListener:(NSObject<UIScrollViewDelegate> *)scrollListener
{
[_scrollListeners addObject:scrollListener];
@@ -965,7 +939,6 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
CGSize contentSize = self.contentSize;
if (!CGSizeEqualToSize(_scrollView.contentSize, contentSize)) {
_scrollView.contentSize = contentSize;
[self centerContentIfNeeded];
}
}
@@ -377,7 +377,6 @@ public class com/facebook/react/ReactRootView : android/widget/FrameLayout, com/
protected fun dispatchJSPointerEvent (Landroid/view/MotionEvent;Z)V
protected fun dispatchJSTouchEvent (Landroid/view/MotionEvent;)V
public fun dispatchKeyEvent (Landroid/view/KeyEvent;)Z
protected fun drawChild (Landroid/graphics/Canvas;Landroid/view/View;J)Z
protected fun finalize ()V
public fun getAppProperties ()Landroid/os/Bundle;
public fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
@@ -426,6 +425,10 @@ public abstract interface class com/facebook/react/ReactRootView$ReactRootViewEv
public abstract fun onAttachedToReactInstance (Lcom/facebook/react/ReactRootView;)V
}
public abstract class com/facebook/react/TurboReactPackage : com/facebook/react/BaseReactPackage {
public fun <init> ()V
}
public abstract interface class com/facebook/react/ViewManagerOnDemandReactPackage {
public abstract fun createViewManager (Lcom/facebook/react/bridge/ReactApplicationContext;Ljava/lang/String;)Lcom/facebook/react/uimanager/ViewManager;
public abstract fun getViewManagerNames (Lcom/facebook/react/bridge/ReactApplicationContext;)Ljava/util/Collection;
@@ -1479,7 +1482,7 @@ public class com/facebook/react/bridge/ReadableNativeArray : com/facebook/react/
public fun getDouble (I)D
public fun getDynamic (I)Lcom/facebook/react/bridge/Dynamic;
public fun getInt (I)I
public static final fun getJNIPassCounter ()I
public static fun getJNIPassCounter ()I
public fun getLong (I)J
public synthetic fun getMap (I)Lcom/facebook/react/bridge/ReadableMap;
public fun getMap (I)Lcom/facebook/react/bridge/ReadableNativeMap;
@@ -1619,7 +1622,7 @@ public abstract interface class com/facebook/react/bridge/WritableMap : com/face
public abstract fun putString (Ljava/lang/String;Ljava/lang/String;)V
}
public final class com/facebook/react/bridge/WritableNativeArray : com/facebook/react/bridge/ReadableNativeArray, com/facebook/react/bridge/WritableArray {
public class com/facebook/react/bridge/WritableNativeArray : com/facebook/react/bridge/ReadableNativeArray, com/facebook/react/bridge/WritableArray {
public fun <init> ()V
public fun pushArray (Lcom/facebook/react/bridge/ReadableArray;)V
public fun pushBoolean (Z)V
@@ -2036,9 +2039,9 @@ public final class com/facebook/react/defaults/DefaultReactHost {
public static final field INSTANCE Lcom/facebook/react/defaults/DefaultReactHost;
public static final fun getDefaultReactHost (Landroid/content/Context;Lcom/facebook/react/ReactNativeHost;)Lcom/facebook/react/ReactHost;
public static final fun getDefaultReactHost (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;)Lcom/facebook/react/ReactHost;
public static final fun getDefaultReactHost (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;Lkotlin/jvm/functions/Function1;Lcom/facebook/react/runtime/BindingsInstaller;)Lcom/facebook/react/ReactHost;
public static final fun getDefaultReactHost (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;Lkotlin/jvm/functions/Function1;)Lcom/facebook/react/ReactHost;
public static synthetic fun getDefaultReactHost$default (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;ILjava/lang/Object;)Lcom/facebook/react/ReactHost;
public static synthetic fun getDefaultReactHost$default (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;Lkotlin/jvm/functions/Function1;Lcom/facebook/react/runtime/BindingsInstaller;ILjava/lang/Object;)Lcom/facebook/react/ReactHost;
public static synthetic fun getDefaultReactHost$default (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/facebook/react/ReactHost;
}
public abstract class com/facebook/react/defaults/DefaultReactNativeHost : com/facebook/react/ReactNativeHost {
@@ -2059,7 +2062,6 @@ public final class com/facebook/react/defaults/DefaultTurboModuleManagerDelegate
public fun <init> ()V
public final fun addCxxReactPackage (Lkotlin/jvm/functions/Function0;)Lcom/facebook/react/defaults/DefaultTurboModuleManagerDelegate$Builder;
public final fun addCxxReactPackage (Lkotlin/jvm/functions/Function1;)Lcom/facebook/react/defaults/DefaultTurboModuleManagerDelegate$Builder;
public final fun addCxxReactPackages (Lkotlin/jvm/functions/Function1;)Lcom/facebook/react/defaults/DefaultTurboModuleManagerDelegate$Builder;
public synthetic fun build (Lcom/facebook/react/bridge/ReactApplicationContext;Ljava/util/List;)Lcom/facebook/react/ReactPackageTurboModuleManagerDelegate;
}
@@ -2219,7 +2221,6 @@ public abstract interface class com/facebook/react/devsupport/HMRClient : com/fa
public final class com/facebook/react/devsupport/InspectorFlags {
public static final field INSTANCE Lcom/facebook/react/devsupport/InspectorFlags;
public static final fun getFuseboxEnabled ()Z
public static final fun getIsProfilingBuild ()Z
}
public class com/facebook/react/devsupport/InspectorPackagerConnection : com/facebook/react/devsupport/IInspectorPackagerConnection {
@@ -2761,7 +2762,6 @@ public class com/facebook/react/fabric/mounting/MountingManager {
public fun attachRootView (ILandroid/view/View;Lcom/facebook/react/uimanager/ThemedReactContext;)V
public fun clearJSResponder ()V
public fun enqueuePendingEvent (IILjava/lang/String;ZLcom/facebook/react/bridge/WritableMap;I)V
public fun experimental_prefetchResource (Lcom/facebook/react/bridge/ReactContext;Ljava/lang/String;IILcom/facebook/react/common/mapbuffer/MapBuffer;)V
public fun getEventEmitter (II)Lcom/facebook/react/fabric/events/EventEmitterWrapper;
public fun getSurfaceManager (I)Lcom/facebook/react/fabric/mounting/SurfaceMountingManager;
public fun getSurfaceManagerEnforced (ILjava/lang/String;)Lcom/facebook/react/fabric/mounting/SurfaceMountingManager;
@@ -2961,9 +2961,11 @@ public abstract interface annotation class com/facebook/react/module/annotations
public final class com/facebook/react/module/model/ReactModuleInfo {
public static final field Companion Lcom/facebook/react/module/model/ReactModuleInfo$Companion;
public fun <init> (Ljava/lang/String;Ljava/lang/String;ZZZZ)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;ZZZZZ)V
public final fun canOverrideExistingModule ()Z
public static final fun classIsTurboModule (Ljava/lang/Class;)Z
public final fun className ()Ljava/lang/String;
public final fun hasConstants ()Z
public final fun isCxxModule ()Z
public final fun isTurboModule ()Z
public final fun name ()Ljava/lang/String;
@@ -3593,23 +3595,24 @@ public final class com/facebook/react/modules/statusbar/StatusBarModule : com/fa
public final class com/facebook/react/modules/statusbar/StatusBarModule$Companion {
}
public final class com/facebook/react/modules/systeminfo/AndroidInfoHelpers {
public class com/facebook/react/modules/systeminfo/AndroidInfoHelpers {
public static final field DEVICE_LOCALHOST Ljava/lang/String;
public static final field EMULATOR_LOCALHOST Ljava/lang/String;
public static final field GENYMOTION_LOCALHOST Ljava/lang/String;
public static final field INSTANCE Lcom/facebook/react/modules/systeminfo/AndroidInfoHelpers;
public static final field METRO_HOST_PROP_NAME Ljava/lang/String;
public static final fun getAdbReverseTcpCommand (I)Ljava/lang/String;
public static final fun getAdbReverseTcpCommand (Landroid/content/Context;)Ljava/lang/String;
public static final fun getFriendlyDeviceName ()Ljava/lang/String;
public static final fun getInspectorHostMetadata (Landroid/content/Context;)Ljava/util/Map;
public static final fun getServerHost (I)Ljava/lang/String;
public static final fun getServerHost (Landroid/content/Context;)Ljava/lang/String;
public fun <init> ()V
public static fun getAdbReverseTcpCommand (Landroid/content/Context;)Ljava/lang/String;
public static fun getAdbReverseTcpCommand (Ljava/lang/Integer;)Ljava/lang/String;
public static fun getFriendlyDeviceName ()Ljava/lang/String;
public static fun getInspectorHostMetadata (Landroid/content/Context;)Ljava/util/Map;
public static fun getServerHost (Landroid/content/Context;)Ljava/lang/String;
public static fun getServerHost (Ljava/lang/Integer;)Ljava/lang/String;
}
public final class com/facebook/react/modules/systeminfo/AndroidInfoModule : com/facebook/fbreact/specs/NativePlatformConstantsAndroidSpec {
public class com/facebook/react/modules/systeminfo/AndroidInfoModule : com/facebook/fbreact/specs/NativePlatformConstantsAndroidSpec, com/facebook/react/turbomodule/core/interfaces/TurboModule {
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;)V
public fun getAndroidID ()Ljava/lang/String;
public fun getTypedExportedConstants ()Ljava/util/Map;
public fun invalidate ()V
}
@@ -5283,8 +5286,6 @@ public abstract class com/facebook/react/uimanager/ViewManager : com/facebook/re
public fun createView (ILcom/facebook/react/uimanager/ThemedReactContext;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;Lcom/facebook/react/touch/JSResponderHandler;)Landroid/view/View;
protected fun createViewInstance (ILcom/facebook/react/uimanager/ThemedReactContext;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Landroid/view/View;
protected abstract fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View;
protected fun experimental_isPrefetchingEnabled ()Z
public fun experimental_prefetchResource (Lcom/facebook/react/bridge/ReactContext;IILcom/facebook/react/common/mapbuffer/MapBuffer;)V
public fun getCommandsMap ()Ljava/util/Map;
protected fun getDelegate ()Lcom/facebook/react/uimanager/ViewManagerDelegate;
public fun getExportedCustomBubblingEventTypeConstants ()Ljava/util/Map;
@@ -7829,6 +7830,8 @@ public class com/facebook/react/views/view/ReactDrawableHelper {
public class com/facebook/react/views/view/ReactViewGroup : android/view/ViewGroup, com/facebook/react/touch/ReactHitSlopView, com/facebook/react/touch/ReactInterceptingViewGroup, com/facebook/react/uimanager/ReactClippingViewGroup, com/facebook/react/uimanager/ReactOverflowViewWithInset, com/facebook/react/uimanager/ReactPointerEventsView, com/facebook/react/uimanager/ReactZIndexedViewGroup {
public fun <init> (Landroid/content/Context;)V
public fun addView (Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
protected fun addViewInLayout (Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;Z)Z
protected fun dispatchDraw (Landroid/graphics/Canvas;)V
public fun dispatchGenericMotionEvent (Landroid/view/MotionEvent;)Z
public fun dispatchProvideStructure (Landroid/view/ViewStructure;)V
@@ -7836,6 +7839,7 @@ public class com/facebook/react/views/view/ReactViewGroup : android/view/ViewGro
public fun draw (Landroid/graphics/Canvas;)V
protected fun drawChild (Landroid/graphics/Canvas;Landroid/view/View;J)Z
protected fun getChildDrawingOrder (II)I
public fun getChildVisibleRect (Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;)Z
public fun getClippingRect (Landroid/graphics/Rect;)V
public fun getHitSlopRect ()Landroid/graphics/Rect;
public fun getOverflow ()Ljava/lang/String;
@@ -7851,8 +7855,11 @@ public class com/facebook/react/views/view/ReactViewGroup : android/view/ViewGro
protected fun onMeasure (II)V
protected fun onSizeChanged (IIII)V
public fun onTouchEvent (Landroid/view/MotionEvent;)Z
public fun onViewAdded (Landroid/view/View;)V
public fun onViewRemoved (Landroid/view/View;)V
public fun removeView (Landroid/view/View;)V
public fun removeViewAt (I)V
public fun removeViewInLayout (Landroid/view/View;)V
public fun removeViews (II)V
public fun removeViewsInLayout (II)V
public fun requestLayout ()V
public fun setBackfaceVisibility (Ljava/lang/String;)V
public fun setBackfaceVisibilityDependantOpacity ()V
@@ -37,13 +37,9 @@ fun getSDKPath(): String {
fun getSDKManagerPath(): String {
val metaSdkManagerPath = File("${getSDKPath()}/cmdline-tools/latest/bin/sdkmanager")
val ossSdkManagerPath = File("${getSDKPath()}/tools/bin/sdkmanager")
val windowsMetaSdkManagerPath = File("${getSDKPath()}/cmdline-tools/latest/bin/sdkmanager.bat")
val windowsOssSdkManagerPath = File("${getSDKPath()}/tools/bin/sdkmanager.bat")
return when {
metaSdkManagerPath.exists() -> metaSdkManagerPath.absolutePath
windowsMetaSdkManagerPath.exists() -> windowsMetaSdkManagerPath.absolutePath
ossSdkManagerPath.exists() -> ossSdkManagerPath.absolutePath
windowsOssSdkManagerPath.exists() -> windowsOssSdkManagerPath.absolutePath
else -> throw GradleException("Could not find sdkmanager executable.")
}
}
@@ -8,6 +8,7 @@
package com.facebook.react;
import static com.facebook.react.ReactInstanceManager.initializeSoLoaderIfNecessary;
import static com.facebook.react.modules.systeminfo.AndroidInfoHelpers.getFriendlyDeviceName;
import android.app.Activity;
import android.app.Application;
@@ -36,7 +37,6 @@ import com.facebook.react.internal.ChoreographerProvider;
import com.facebook.react.jscexecutor.JSCExecutor;
import com.facebook.react.jscexecutor.JSCExecutorFactory;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.modules.systeminfo.AndroidInfoHelpers;
import com.facebook.react.packagerconnection.RequestHandler;
import java.util.ArrayList;
import java.util.List;
@@ -339,7 +339,7 @@ public class ReactInstanceManagerBuilder {
// We use the name of the device and the app for debugging & metrics
//noinspection ConstantConditions
String appName = mApplication.getPackageName();
String deviceName = AndroidInfoHelpers.getFriendlyDeviceName();
String deviceName = getFriendlyDeviceName();
return new ReactInstanceManager(
mApplication,
@@ -8,16 +8,13 @@
package com.facebook.react;
import static com.facebook.infer.annotation.ThreadConfined.UI;
import static com.facebook.react.uimanager.BlendModeHelper.needsIsolatedLayer;
import static com.facebook.react.uimanager.common.UIManagerType.DEFAULT;
import static com.facebook.react.uimanager.common.UIManagerType.FABRIC;
import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
import android.content.Context;
import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.Insets;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Build;
@@ -68,7 +65,6 @@ import com.facebook.react.uimanager.RootView;
import com.facebook.react.uimanager.RootViewUtil;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.common.UIManagerType;
import com.facebook.react.uimanager.common.ViewUtil;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.systrace.Systrace;
import java.util.concurrent.atomic.AtomicInteger;
@@ -294,30 +290,6 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
}
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
BlendMode mixBlendMode = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
&& ViewUtil.getUIManagerType(this) == UIManagerType.FABRIC
&& needsIsolatedLayer(this)) {
mixBlendMode = (BlendMode) child.getTag(R.id.mix_blend_mode);
if (mixBlendMode != null) {
Paint p = new Paint();
p.setBlendMode(mixBlendMode);
canvas.saveLayer(0, 0, getWidth(), getHeight(), p);
}
}
boolean result = super.drawChild(canvas, child, drawingTime);
if (mixBlendMode != null) {
canvas.restore();
}
return result;
}
@Override
public boolean dispatchKeyEvent(KeyEvent ev) {
if (!hasActiveReactContext() || !isViewAttachedToReactInstance()) {
@@ -0,0 +1,14 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react;
import com.facebook.react.common.annotations.DeprecatedInNewArchitecture;
/** This will eventually replace {@link LazyReactPackage} when TurboModules are finally done. */
@DeprecatedInNewArchitecture(message = "Use BaseReactPackage instead")
public abstract class TurboReactPackage extends BaseReactPackage {}
@@ -130,7 +130,7 @@ public class InterpolationAnimatedNode(config: ReadableMap) : ValueAnimatedNode(
val outputRange = arrayOfNulls<DoubleArray>(size)
// Match the first pattern into a List, since we don't know its length yet
var m = numericPattern.matcher(array.getString(0) ?: "")
var m = numericPattern.matcher(array.getString(0))
val firstOutputRange: MutableList<Double> = ArrayList()
while (m.find()) {
firstOutputRange.add(m.group().toDouble())
@@ -143,7 +143,7 @@ public class InterpolationAnimatedNode(config: ReadableMap) : ValueAnimatedNode(
for (i in 1 until size) {
val outputArr = DoubleArray(firstOutputRangeArr.size)
var j = 0
m = numericPattern.matcher(array.getString(i) ?: "")
m = numericPattern.matcher(array.getString(i))
while (m.find() && j < firstOutputRangeArr.size) {
outputArr[j++] = m.group().toDouble()
}
@@ -45,9 +45,7 @@ internal class ObjectAnimatedNode(
ReadableType.String -> result.pushString(source.getString(i))
ReadableType.Map -> {
val map = source.getMap(i)
if (map != null &&
map.hasKey(NODE_TAG_KEY) &&
map.getType(NODE_TAG_KEY) == ReadableType.Number) {
if (map.hasKey(NODE_TAG_KEY) && map.getType(NODE_TAG_KEY) == ReadableType.Number) {
val node = nativeAnimatedNodesManager.getNodeById(map.getInt(NODE_TAG_KEY))
requireNotNull(node) { "Mapped value node does not exist" }
if (node is ValueAnimatedNode) {
@@ -19,15 +19,15 @@ internal class TransformAnimatedNode(
config: ReadableMap,
private val nativeAnimatedNodesManager: NativeAnimatedNodesManager
) : AnimatedNode() {
private val transformConfigs: List<TransformConfig>
private val transformConfigs: MutableList<TransformConfig>
init {
val transforms = config.getArray("transforms")
transformConfigs =
if (transforms == null) emptyList()
if (transforms == null) mutableListOf()
else
List<TransformConfig>(transforms.size()) { i ->
val transformConfigMap = checkNotNull(transforms.getMap(i))
MutableList<TransformConfig>(transforms.size()) { i ->
val transformConfigMap = transforms.getMap(i)
val property = transformConfigMap.getString("property")
val type = transformConfigMap.getString("type")
if (type == "animated") {
@@ -46,7 +46,7 @@ internal class TransformAnimatedNode(
public fun collectViewUpdates(propsMap: JavaOnlyMap) {
val transforms =
List<JavaOnlyMap>(transformConfigs.size) { i ->
MutableList<JavaOnlyMap>(transformConfigs.size) { i ->
val transformConfig = transformConfigs[i]
val transform =
if (transformConfig is AnimatedTransformConfig) {
@@ -34,7 +34,7 @@ public class ColorPropConverter {
private static final String ATTR_SEGMENT = "attr/";
@Nullable
private static Integer getColorInteger(@Nullable Object value, Context context) {
private static Integer getColorInteger(Object value, Context context) {
if (value == null) {
return null;
}
@@ -84,7 +84,7 @@ public class ColorPropConverter {
}
@Nullable
public static Color getColorInstance(@Nullable Object value, Context context) {
public static Color getColorInstance(Object value, Context context) {
if (value == null) {
return null;
}
@@ -136,7 +136,7 @@ public class ColorPropConverter {
"ColorValue: the value must be a number or Object.");
}
public static Integer getColor(@Nullable Object value, Context context) {
public static Integer getColor(Object value, Context context) {
try {
if (supportWideGamut()) {
Color color = getColorInstance(value, context);
@@ -150,7 +150,7 @@ public class ColorPropConverter {
return getColorInteger(value, context);
}
public static Integer getColor(@Nullable Object value, Context context, int defaultInt) {
public static Integer getColor(Object value, Context context, int defaultInt) {
try {
return getColor(value, context);
} catch (JSApplicationCausedNativeException e) {
@@ -73,13 +73,13 @@ public class JavaOnlyArray : ReadableArray, WritableArray {
override fun getLong(index: Int): Long = (backingList[index] as Number).toLong()
override fun getString(index: Int): String? = backingList[index] as String?
override fun getString(index: Int): String = backingList[index] as String
override fun getArray(index: Int): ReadableArray? = backingList[index] as ReadableArray?
override fun getArray(index: Int): ReadableArray = backingList[index] as ReadableArray
override fun getBoolean(index: Int): Boolean = backingList[index] as Boolean
override fun getMap(index: Int): ReadableMap? = backingList[index] as ReadableMap?
override fun getMap(index: Int): ReadableMap = backingList[index] as ReadableMap
override fun getDynamic(index: Int): Dynamic = DynamicFromArray.create(this, index)
@@ -25,6 +25,7 @@ import com.facebook.react.bridge.interop.InteropModuleRegistry;
import com.facebook.react.bridge.queue.MessageQueueThread;
import com.facebook.react.bridge.queue.ReactQueueConfiguration;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.common.annotations.DeprecatedInNewArchitecture;
import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder;
import java.lang.ref.WeakReference;
import java.util.Collection;
@@ -502,8 +503,8 @@ public abstract class ReactContext extends ContextWrapper {
*/
public abstract @Nullable CallInvokerHolder getJSCallInvokerHolder();
@Deprecated(
since =
@DeprecatedInNewArchitecture(
message =
"This method will be deprecated later as part of Stable APIs with bridge removal and not"
+ " encouraged usage.")
/**
@@ -14,7 +14,7 @@ import java.util.ArrayList
* to Kotlin.
*/
public interface ReadableArray {
public fun getArray(index: Int): ReadableArray?
public fun getArray(index: Int): ReadableArray
public fun getBoolean(index: Int): Boolean
@@ -26,9 +26,9 @@ public interface ReadableArray {
public fun getLong(index: Int): Long
public fun getMap(index: Int): ReadableMap?
public fun getMap(index: Int): ReadableMap
public fun getString(index: Int): String?
public fun getString(index: Int): String
public fun getType(index: Int): ReadableType
@@ -0,0 +1,171 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.bridge;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.facebook.infer.annotation.Assertions;
import com.facebook.proguard.annotations.DoNotStrip;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Implementation of a NativeArray that allows read-only access to its members. This will generally
* be constructed and filled in native code so you shouldn't construct one yourself.
*/
@DoNotStrip
public class ReadableNativeArray extends NativeArray implements ReadableArray {
static {
ReactBridge.staticInit();
}
protected ReadableNativeArray() {}
// WriteOnce but not in the constructor fields
private @Nullable Object[] mLocalArray;
private @Nullable ReadableType[] mLocalTypeArray;
private static int jniPassCounter = 0;
public static int getJNIPassCounter() {
return jniPassCounter;
}
private Object[] getLocalArray() {
if (mLocalArray != null) {
return mLocalArray;
}
synchronized (this) {
// Make sure no concurrent call already updated
if (mLocalArray == null) {
jniPassCounter++;
mLocalArray = Assertions.assertNotNull(importArray());
}
}
return mLocalArray;
}
private native Object[] importArray();
private ReadableType[] getLocalTypeArray() {
if (mLocalTypeArray != null) {
return mLocalTypeArray;
}
synchronized (this) {
// Make sure no concurrent call already updated
if (mLocalTypeArray == null) {
jniPassCounter++;
Object[] tempArray = Assertions.assertNotNull(importTypeArray());
mLocalTypeArray = Arrays.copyOf(tempArray, tempArray.length, ReadableType[].class);
}
}
return mLocalTypeArray;
}
private native Object[] importTypeArray();
@Override
public int size() {
return getLocalArray().length;
}
@Override
public boolean isNull(int index) {
return getLocalArray()[index] == null;
}
@Override
public boolean getBoolean(int index) {
return ((Boolean) getLocalArray()[index]).booleanValue();
}
@Override
public double getDouble(int index) {
return ((Double) getLocalArray()[index]).doubleValue();
}
@Override
public int getInt(int index) {
return ((Double) getLocalArray()[index]).intValue();
}
@Override
public long getLong(int index) {
return ((Long) getLocalArray()[index]).longValue();
}
@Override
public @NonNull String getString(int index) {
return (String) getLocalArray()[index];
}
@Override
public @NonNull ReadableNativeArray getArray(int index) {
return (ReadableNativeArray) getLocalArray()[index];
}
@Override
public @NonNull ReadableNativeMap getMap(int index) {
return (ReadableNativeMap) getLocalArray()[index];
}
@Override
public @NonNull ReadableType getType(int index) {
return getLocalTypeArray()[index];
}
@Override
public @NonNull Dynamic getDynamic(int index) {
return DynamicFromArray.create(this, index);
}
@Override
public int hashCode() {
return getLocalArray().hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ReadableNativeArray)) {
return false;
}
ReadableNativeArray other = (ReadableNativeArray) obj;
return Arrays.deepEquals(getLocalArray(), other.getLocalArray());
}
@Override
public @NonNull ArrayList<Object> toArrayList() {
ArrayList<Object> arrayList = new ArrayList<>();
for (int i = 0; i < this.size(); i++) {
switch (getType(i)) {
case Null:
arrayList.add(null);
break;
case Boolean:
arrayList.add(getBoolean(i));
break;
case Number:
arrayList.add(getDouble(i));
break;
case String:
arrayList.add(getString(i));
break;
case Map:
arrayList.add(getMap(i).toHashMap());
break;
case Array:
arrayList.add(getArray(i).toArrayList());
break;
default:
throw new IllegalArgumentException("Could not convert object at index: " + i + ".");
}
}
return arrayList;
}
}
@@ -1,92 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.bridge
import com.facebook.proguard.annotations.DoNotStrip
import java.util.ArrayList
import java.util.Arrays
import kotlin.jvm.JvmStatic
/**
* Implementation of a NativeArray that allows read-only access to its members. This will generally
* be constructed and filled in native code so you shouldn't construct one yourself.
*/
@DoNotStrip
public open class ReadableNativeArray protected constructor() : NativeArray(), ReadableArray {
private val localArray: Array<Any?> by
lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
jniPassCounter++
importArray()
}
private external fun importArray(): Array<Any?>
private val localTypeArray: Array<ReadableType> by
lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
jniPassCounter++
val tempArray = importTypeArray()
Arrays.copyOf(tempArray, tempArray.size, Array<ReadableType>::class.java)
}
private external fun importTypeArray(): Array<Any>
override fun size(): Int = localArray.size
override fun isNull(index: Int): Boolean = localArray[index] == null
override fun getBoolean(index: Int): Boolean = localArray[index] as Boolean
override fun getDouble(index: Int): Double = localArray[index] as Double
override fun getInt(index: Int): Int = (localArray[index] as Double).toInt()
override fun getLong(index: Int): Long = localArray[index] as Long
override fun getString(index: Int): String? = localArray[index] as String?
override fun getArray(index: Int): ReadableNativeArray? =
localArray[index] as ReadableNativeArray?
override fun getMap(index: Int): ReadableNativeMap? = localArray[index] as ReadableNativeMap?
override fun getType(index: Int): ReadableType = localTypeArray[index]
override fun getDynamic(index: Int): Dynamic = DynamicFromArray.create(this, index)
override fun hashCode(): Int = localArray.hashCode()
override fun equals(other: Any?): Boolean {
if (other !is ReadableNativeArray) {
return false
}
return localArray.contentDeepEquals(other.localArray)
}
override fun toArrayList(): ArrayList<Any?> {
val arrayList = ArrayList<Any?>()
repeat(size()) { i ->
when (getType(i)) {
ReadableType.Null -> arrayList.add(null)
ReadableType.Boolean -> arrayList.add(getBoolean(i))
ReadableType.Number -> arrayList.add(getDouble(i))
ReadableType.String -> arrayList.add(getString(i))
ReadableType.Map -> arrayList.add(getMap(i)?.toHashMap())
ReadableType.Array -> arrayList.add(getArray(i)?.toArrayList())
}
}
return arrayList
}
private companion object {
@get:JvmStatic
@get:JvmName("getJNIPassCounter")
public var jniPassCounter: Int = 0
private set
}
}
@@ -177,9 +177,12 @@ public open class ReadableNativeMap protected constructor() : NativeMap(), Reada
}
private companion object {
@get:JvmStatic
@get:JvmName("getJNIPassCounter")
public var jniPassCounter: Int = 0
private set
init {
ReactBridge.staticInit()
}
private var jniPassCounter: Int = 0
@JvmStatic public fun getJNIPassCounter(): Int = jniPassCounter
}
}
@@ -0,0 +1,67 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.bridge;
import androidx.annotation.Nullable;
import com.facebook.infer.annotation.Assertions;
import com.facebook.proguard.annotations.DoNotStrip;
/**
* Implementation of a write-only array stored in native memory. Use {@link Arguments#createArray()}
* if you need to stub out creating this class in a test. TODO(5815532): Check if consumed on read
*/
@DoNotStrip
public class WritableNativeArray extends ReadableNativeArray implements WritableArray {
static {
ReactBridge.staticInit();
}
public WritableNativeArray() {
initHybrid();
}
@Override
public native void pushNull();
@Override
public native void pushBoolean(boolean value);
@Override
public native void pushDouble(double value);
@Override
public native void pushInt(int value);
@Override
public native void pushLong(long value);
@Override
public native void pushString(@Nullable String value);
// Note: this consumes the map so do not reuse it.
@Override
public void pushArray(@Nullable ReadableArray array) {
Assertions.assertCondition(
array == null || array instanceof ReadableNativeArray, "Illegal type provided");
pushNativeArray((ReadableNativeArray) array);
}
// Note: this consumes the map so do not reuse it.
@Override
public void pushMap(@Nullable ReadableMap map) {
Assertions.assertCondition(
map == null || map instanceof ReadableNativeMap, "Illegal type provided");
pushNativeMap((ReadableNativeMap) map);
}
private native void initHybrid();
private native void pushNativeArray(ReadableNativeArray array);
private native void pushNativeMap(ReadableNativeMap map);
}
@@ -1,52 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.bridge
import com.facebook.proguard.annotations.DoNotStrip
/**
* Implementation of a write-only array stored in native memory. Use [Arguments#createArray()] if
* you need to stub out creating this class in a test.
*/
@DoNotStrip
public class WritableNativeArray : ReadableNativeArray(), WritableArray {
init {
initHybrid()
}
external override fun pushNull()
external override fun pushBoolean(value: Boolean)
external override fun pushDouble(value: Double)
external override fun pushInt(value: Int)
external override fun pushLong(value: Long)
external override fun pushString(value: String?)
// Note: this consumes the map so do not reuse it.
override fun pushArray(array: ReadableArray?) {
check(array == null || array is ReadableNativeArray) { "Illegal type provided" }
pushNativeArray(array as ReadableNativeArray?)
}
// Note: this consumes the map so do not reuse it.
override fun pushMap(map: ReadableMap?) {
check(map == null || map is ReadableNativeMap) { "Illegal type provided" }
pushNativeMap(map as ReadableNativeMap?)
}
private external fun initHybrid()
private external fun pushNativeArray(array: ReadableNativeArray?)
private external fun pushNativeMap(map: ReadableNativeMap?)
}
@@ -63,4 +63,10 @@ public class WritableNativeMap : ReadableNativeMap(), WritableMap {
private external fun mergeNativeMap(source: ReadableNativeMap)
private external fun initHybrid()
private companion object {
init {
ReactBridge.staticInit()
}
}
}
@@ -5,39 +5,42 @@
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.common
package com.facebook.react.common;
import com.facebook.infer.annotation.Nullsafe;
/**
* Interface for handling a surface in React Native. In mobile platform a surface can be any
* container that holds some [View]. For example, a Dialog can be a surface to wrap content view
* object as needed. In VR platform, a surface is provided by Shell panel app sdk, which requires
* custom logic to show/hide. NativeModules requires a surface will delegate interactions with the
* surface to a SurfaceDelegate.
* container that holds some {@link View}. For example, a Dialog can be a surface to wrap content
* view object as needed. In VR platform, a surface is provided by Shell panel app sdk, which
* requires custom logic to show/hide. NativeModules requires a surface will delegate interactions
* with the surface to a SurfaceDelegate.
*/
@Nullsafe(Nullsafe.Mode.LOCAL)
public interface SurfaceDelegate {
/**
* Create the React content view that uses the appKey as the React application name
*
* @param appKey
*/
public fun createContentView(appKey: String): Unit
void createContentView(String appKey);
/**
* Check if the content view is created and ready to be shown
*
* @return true if the content view is ready to be shown
*/
public fun isContentViewReady(): Boolean
boolean isContentViewReady();
/** Destroy the React content view to avoid memory leak */
public fun destroyContentView(): Unit
void destroyContentView();
/** Show the surface containing the React content view */
public fun show(): Unit
void show();
/** Hide the surface containing the React content view */
public fun hide(): Unit
void hide();
/** Check if the surface is currently showing */
public fun isShowing(): Boolean
boolean isShowing();
}
@@ -16,7 +16,6 @@ import com.facebook.react.bridge.ReactContext
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.common.build.ReactBuildConfig
import com.facebook.react.fabric.ComponentFactory
import com.facebook.react.runtime.BindingsInstaller
import com.facebook.react.runtime.JSCInstance
import com.facebook.react.runtime.ReactHostImpl
import com.facebook.react.runtime.cxxreactpackage.CxxReactPackage
@@ -43,12 +42,11 @@ public object DefaultReactHost {
* `index.<platform>`
* @param jsBundleAssetPath the path to the JS bundle relative to the assets directory. Will be
* composed in a `asset://...` URL
* @param jsBundleFilePath the path to the JS bundle on the filesystem. Will be composed in a
* `file://...` URL
* @param isHermesEnabled whether to use Hermes as the JS engine, default to true.
* @param useDevSupport whether to enable dev support, default to ReactBuildConfig.DEBUG.
* @param cxxReactPackageProviders a list of cxxreactpackage providers (to register c++ turbo
* modules)
* @param jsBundleLoader a [JSBundleLoader] to use for creating the [ReactHost]
*
* TODO(T186951312): Should this be @UnstableReactNativeAPI?
*/
@@ -72,9 +70,9 @@ public object DefaultReactHost {
jsBundleFilePath,
isHermesEnabled,
useDevSupport,
cxxReactPackageProviders,
{ throw it },
null)
cxxReactPackageProviders) {
throw it
}
/**
* Util function to create a default [ReactHost] to be used in your application. This method is
@@ -86,15 +84,13 @@ public object DefaultReactHost {
* `index.<platform>`
* @param jsBundleAssetPath the path to the JS bundle relative to the assets directory. Will be
* composed in a `asset://...` URL
* @param jsBundleFilePath the path to the JS bundle on the filesystem. Will be composed in a
* `file://...` URL
* @param isHermesEnabled whether to use Hermes as the JS engine, default to true.
* @param useDevSupport whether to enable dev support, default to ReactBuildConfig.DEBUG.
* @param cxxReactPackageProviders a list of cxxreactpackage providers (to register c++ turbo
* modules)
* @param jsBundleLoader a [JSBundleLoader] to use for creating the [ReactHost]
* @param exceptionHandler Callback that can be used by React Native host applications to react to
* exceptions thrown by the internals of React Native.
* @param bindingsInstaller that can be used for installing bindings.
*
* TODO(T186951312): Should this be @UnstableReactNativeAPI?
*/
@@ -110,7 +106,6 @@ public object DefaultReactHost {
useDevSupport: Boolean = ReactBuildConfig.DEBUG,
cxxReactPackageProviders: List<(ReactContext) -> CxxReactPackage> = emptyList(),
exceptionHandler: (Exception) -> Unit = { throw it },
bindingsInstaller: BindingsInstaller? = null,
): ReactHost {
if (reactHost == null) {
@@ -133,7 +128,6 @@ public object DefaultReactHost {
jsBundleLoader = bundleLoader,
reactPackages = packageList,
jsRuntimeFactory = jsRuntimeFactory,
bindingsInstaller = bindingsInstaller,
turboModuleManagerDelegateBuilder = defaultTmmDelegateBuilder,
exceptionHandler = exceptionHandler)
val componentFactory = ComponentFactory()
@@ -40,27 +40,33 @@ private constructor(
}
public class Builder : ReactPackageTurboModuleManagerDelegate.Builder() {
private val cxxReactPackageProviders =
mutableListOf<(context: ReactApplicationContext) -> List<CxxReactPackage>>()
private var cxxReactPackageProviders:
MutableList<((context: ReactApplicationContext) -> CxxReactPackage)> =
mutableListOf()
public fun addCxxReactPackage(provider: () -> CxxReactPackage): Builder = apply {
cxxReactPackageProviders.add { _ -> listOf(provider()) }
public fun addCxxReactPackage(provider: () -> CxxReactPackage): Builder {
cxxReactPackageProviders.add { _ -> provider() }
return this
}
public fun addCxxReactPackage(
provider: (context: ReactApplicationContext) -> CxxReactPackage
): Builder = apply { cxxReactPackageProviders.add { context -> listOf(provider(context)) } }
public fun addCxxReactPackages(
provider: (context: ReactApplicationContext) -> List<CxxReactPackage>
): Builder = apply { cxxReactPackageProviders.add(provider) }
): Builder {
cxxReactPackageProviders.add(provider)
return this
}
override fun build(
context: ReactApplicationContext,
packages: List<ReactPackage>
): DefaultTurboModuleManagerDelegate =
DefaultTurboModuleManagerDelegate(
context, packages, cxxReactPackageProviders.flatMap { provider -> provider(context) })
): DefaultTurboModuleManagerDelegate {
val cxxReactPackages = mutableListOf<CxxReactPackage>()
for (cxxReactPackageProvider in cxxReactPackageProviders) {
cxxReactPackages.add(cxxReactPackageProvider(context))
}
return DefaultTurboModuleManagerDelegate(context, packages, cxxReactPackages)
}
}
private companion object {
@@ -9,7 +9,6 @@ package com.facebook.react.devsupport
import android.content.Context
import com.facebook.react.common.SurfaceDelegateFactory
import com.facebook.react.common.build.ReactBuildConfig
import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener
import com.facebook.react.devsupport.interfaces.DevLoadingViewManager
import com.facebook.react.devsupport.interfaces.DevSupportManager
@@ -102,11 +101,7 @@ public class DefaultDevSupportManagerFactory : DevSupportManagerFactory {
useDevSupport: Boolean
): DevSupportManager =
if (!useDevSupport) {
if (ReactBuildConfig.UNSTABLE_ENABLE_FUSEBOX_RELEASE) {
PerftestDevSupportManager(applicationContext)
} else {
ReleaseDevSupportManager()
}
ReleaseDevSupportManager()
} else {
BridgelessDevSupportManager(
applicationContext,
@@ -325,12 +325,11 @@ public class DevServerHelper {
private String getInspectorDeviceUrl() {
return String.format(
Locale.US,
"http://%s/inspector/device?name=%s&app=%s&device=%s&profiling=%b",
"http://%s/inspector/device?name=%s&app=%s&device=%s",
mPackagerConnectionSettings.getDebugServerHost(),
Uri.encode(AndroidInfoHelpers.getFriendlyDeviceName()),
Uri.encode(mPackageName),
Uri.encode(getInspectorDeviceId()),
InspectorFlags.getIsProfilingBuild());
Uri.encode(getInspectorDeviceId()));
}
public void downloadBundleFromURL(
@@ -17,6 +17,4 @@ public object InspectorFlags {
}
@DoNotStrip @JvmStatic public external fun getFuseboxEnabled(): Boolean
@DoNotStrip @JvmStatic public external fun getIsProfilingBuild(): Boolean
}
@@ -43,7 +43,7 @@ internal class LogBoxDialogSurfaceDelegate(private val devSupportManager: DevSup
}
override fun show() {
if (isShowing() || !isContentViewReady()) {
if (isShowing || !isContentViewReady) {
return
}
val context = devSupportManager.currentActivity
@@ -61,7 +61,7 @@ internal class LogBoxDialogSurfaceDelegate(private val devSupportManager: DevSup
}
override fun hide() {
if (isShowing()) {
if (isShowing) {
dialog?.dismiss()
}
(reactRootView?.parent as ViewGroup?)?.removeView(reactRootView)
@@ -25,7 +25,7 @@ public class LogBoxModule(
override fun show() {
UiThreadUtil.runOnUiThread {
if (!surfaceDelegate.isContentViewReady()) {
if (!surfaceDelegate.isContentViewReady) {
/**
* LogBoxModule can be rendered in different surface. By default, it will use LogBoxDialog
* to wrap the content of logs. In other platform (for example VR), a surfaceDelegate can be
@@ -625,10 +625,10 @@ public class FabricUIManager
* @return if theme data is available in the output parameters.
*/
public boolean getThemeData(int surfaceId, float[] defaultTextInputPadding) {
SurfaceMountingManager surfaceMountingManager = mMountingManager.getSurfaceManager(surfaceId);
Context context = surfaceMountingManager != null ? surfaceMountingManager.getContext() : null;
Context context =
mMountingManager.getSurfaceManagerEnforced(surfaceId, "getThemeData").getContext();
if (context == null) {
FLog.w(TAG, "Couldn't get context for surfaceId %d in getThemeData", surfaceId);
FLog.w(TAG, "\"themedReactContext\" is null when call \"getThemeData\"");
return false;
}
@@ -427,28 +427,6 @@ public class MountingManager {
attachmentsPositions);
}
/**
* @deprecated THIS PREFETCH METHOD IS EXPERIMENTAL, DO NOT USE IT FOR PRODUCTION CODE. IT WILL
* MOST LIKELY CHANGE OR BE REMOVED IN THE FUTURE.
* @param reactContext
* @param componentName
* @param surfaceId {@link int} surface ID
* @param reactTag reactTag that should be set as ID of the view instance
* @param params {@link MapBuffer} prefetch request params defined in C++
*/
@AnyThread
@Deprecated
public void experimental_prefetchResource(
ReactContext reactContext,
String componentName,
int surfaceId,
int reactTag,
MapBuffer params) {
mViewManagerRegistry
.get(componentName)
.experimental_prefetchResource(reactContext, surfaceId, reactTag, params);
}
public void enqueuePendingEvent(
int surfaceId,
int reactTag,
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<6d8d8f4b81d7be882b315d0960499dcb>>
* @generated SignedSource<<b1ad8179cf22c2e97f623435bf152aab>>
*/
/**
@@ -130,12 +130,6 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun enableIOSViewClipToPaddingBox(): Boolean = accessor.enableIOSViewClipToPaddingBox()
/**
* When enabled, Andoid will build and initiate image prefetch requests on ImageShadowNode::layout
*/
@JvmStatic
public fun enableImagePrefetchingAndroid(): Boolean = accessor.enableImagePrefetchingAndroid()
/**
* When enabled, LayoutAnimations API will animate state changes on Android.
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<031fce8e8b4c20a3e3d6dbecf94d138a>>
* @generated SignedSource<<7dd21b62dfe429aecdbd179cb482fb26>>
*/
/**
@@ -37,7 +37,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
private var enableFixForViewCommandRaceCache: Boolean? = null
private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null
private var enableIOSViewClipToPaddingBoxCache: Boolean? = null
private var enableImagePrefetchingAndroidCache: Boolean? = null
private var enableLayoutAnimationsOnAndroidCache: Boolean? = null
private var enableLayoutAnimationsOnIOSCache: Boolean? = null
private var enableLongTaskAPICache: Boolean? = null
@@ -220,15 +219,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
return cached
}
override fun enableImagePrefetchingAndroid(): Boolean {
var cached = enableImagePrefetchingAndroidCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableImagePrefetchingAndroid()
enableImagePrefetchingAndroidCache = cached
}
return cached
}
override fun enableLayoutAnimationsOnAndroid(): Boolean {
var cached = enableLayoutAnimationsOnAndroidCache
if (cached == null) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<35811667ac2543e1f64e27bbdb483ec1>>
* @generated SignedSource<<fcfded14a5fe05501892993c1f58f3ed>>
*/
/**
@@ -62,8 +62,6 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun enableIOSViewClipToPaddingBox(): Boolean
@DoNotStrip @JvmStatic public external fun enableImagePrefetchingAndroid(): Boolean
@DoNotStrip @JvmStatic public external fun enableLayoutAnimationsOnAndroid(): Boolean
@DoNotStrip @JvmStatic public external fun enableLayoutAnimationsOnIOS(): Boolean
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<9d829c58e49164a0b2b6b66bc0ce088a>>
* @generated SignedSource<<86d8dd894e80a788af7f47172d30d33c>>
*/
/**
@@ -57,8 +57,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun enableIOSViewClipToPaddingBox(): Boolean = false
override fun enableImagePrefetchingAndroid(): Boolean = false
override fun enableLayoutAnimationsOnAndroid(): Boolean = false
override fun enableLayoutAnimationsOnIOS(): Boolean = true
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<0121e113410a5b0e14eaf74a3076df2f>>
* @generated SignedSource<<4bb5173b9ba1d3e620f3a7d613b27ac7>>
*/
/**
@@ -41,7 +41,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
private var enableFixForViewCommandRaceCache: Boolean? = null
private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null
private var enableIOSViewClipToPaddingBoxCache: Boolean? = null
private var enableImagePrefetchingAndroidCache: Boolean? = null
private var enableLayoutAnimationsOnAndroidCache: Boolean? = null
private var enableLayoutAnimationsOnIOSCache: Boolean? = null
private var enableLongTaskAPICache: Boolean? = null
@@ -241,16 +240,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun enableImagePrefetchingAndroid(): Boolean {
var cached = enableImagePrefetchingAndroidCache
if (cached == null) {
cached = currentProvider.enableImagePrefetchingAndroid()
accessedFeatureFlags.add("enableImagePrefetchingAndroid")
enableImagePrefetchingAndroidCache = cached
}
return cached
}
override fun enableLayoutAnimationsOnAndroid(): Boolean {
var cached = enableLayoutAnimationsOnAndroidCache
if (cached == null) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<2787d9027695dd14ec6b917a32a1a6de>>
* @generated SignedSource<<2217f2b9992c9424c3d1d221bdfa2236>>
*/
/**
@@ -57,8 +57,6 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun enableIOSViewClipToPaddingBox(): Boolean
@DoNotStrip public fun enableImagePrefetchingAndroid(): Boolean
@DoNotStrip public fun enableLayoutAnimationsOnAndroid(): Boolean
@DoNotStrip public fun enableLayoutAnimationsOnIOS(): Boolean
@@ -14,13 +14,36 @@ import com.facebook.react.turbomodule.core.interfaces.TurboModule
* so Java modules don't have to be instantiated at React Native start up.
*/
public class ReactModuleInfo(
@get:JvmName("name") public val name: String,
@get:JvmName("className") public val className: String,
@get:JvmName("canOverrideExistingModule") public val canOverrideExistingModule: Boolean,
@get:JvmName("needsEagerInit") public val needsEagerInit: Boolean,
private val _name: String,
private val _className: String,
private val _canOverrideExistingModule: Boolean,
private val _needsEagerInit: Boolean,
public val isCxxModule: Boolean,
public val isTurboModule: Boolean
) {
@Deprecated("use ReactModuleInfo(String, String, boolean, boolean, boolean, boolean)]")
public constructor(
name: String,
className: String,
canOverrideExistingModule: Boolean,
needsEagerInit: Boolean,
@Suppress("UNUSED_PARAMETER") hasConstants: Boolean,
isCxxModule: Boolean,
isTurboModule: Boolean
) : this(name, className, canOverrideExistingModule, needsEagerInit, isCxxModule, isTurboModule)
public fun name(): String = _name
public fun className(): String = _className
public fun canOverrideExistingModule(): Boolean = _canOverrideExistingModule
public fun needsEagerInit(): Boolean = _needsEagerInit
@Deprecated("this is hardcoded to return true, regardless if the module has constants or not")
public fun hasConstants(): Boolean = true
public companion object {
/**
* Checks if the passed class is a TurboModule. Useful to populate the parameter [isTurboModule]
@@ -4,8 +4,6 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
@file:Suppress(
"DEPRECATION") // Suppressing deprecation of NotThreadSafeViewHierarchyUpdateDebugListener
package com.facebook.react.modules.debug
@@ -60,9 +60,9 @@ internal class ReactOkHttpNetworkFetcher(private val okHttpClient: OkHttpClient)
val headers = OkHttpCompat.getHeadersFromMap(requestHeaders)
val request =
Request.Builder()
.headers(headers)
.cacheControl(cacheControlBuilder.build())
.url(uri.toString())
.headers(headers)
.get()
.build()
fetchWithRequest(fetchState, callback, request)
@@ -249,8 +249,8 @@ public class ImageLoaderModule : NativeImageLoaderAndroidSpec, LifecycleEventLis
val result: WritableMap = Arguments.createMap()
val imagePipeline: ImagePipeline = this@ImageLoaderModule.imagePipeline
for (i in 0 until uris.size()) {
val uriString = uris.getString(i)
if (!uriString.isNullOrEmpty()) {
val uriString: String = uris.getString(i)
if (uriString.isNotEmpty()) {
val uri = Uri.parse(uriString)
if (imagePipeline.isInBitmapMemoryCache(uri)) {
result.putString(uriString, "memory")
@@ -204,7 +204,7 @@ public open class IntentModule(reactContext: ReactApplicationContext) :
if (extras != null) {
for (i in 0..<extras.size()) {
val map = extras.getMap(i) ?: continue
val map = extras.getMap(i)
val name = map.getString("key")
val type = map.getType(EXTRA_MAP_KEY_FOR_VALUE)
@@ -108,7 +108,7 @@ public class PermissionsModule(reactContext: ReactApplicationContext?) :
var checkedPermissionsCount = 0
val context = getReactApplicationContext().getBaseContext()
for (i in 0 until permissions.size()) {
val perm = permissions.getString(i) ?: continue
val perm = permissions.getString(i)
if (context.checkSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) {
grantedPermissions.putString(perm, GRANTED)
checkedPermissionsCount++
@@ -0,0 +1,175 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.modules.systeminfo;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.os.Build;
import com.facebook.common.logging.FLog;
import com.facebook.react.R;
import com.facebook.react.common.MapBuilder;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Locale;
import java.util.Map;
import javax.annotation.Nullable;
public class AndroidInfoHelpers {
public static final String EMULATOR_LOCALHOST = "10.0.2.2";
public static final String GENYMOTION_LOCALHOST = "10.0.3.2";
public static final String DEVICE_LOCALHOST = "localhost";
public static final String METRO_HOST_PROP_NAME = "metro.host";
private static final String TAG = AndroidInfoHelpers.class.getSimpleName();
private static boolean isRunningOnGenymotion() {
return Build.FINGERPRINT.contains("vbox");
}
private static boolean isRunningOnStockEmulator() {
return Build.FINGERPRINT.contains("generic")
|| Build.FINGERPRINT.startsWith("google/sdk_gphone");
}
public static String getServerHost(Integer port) {
return getServerIpAddress(port);
}
public static String getServerHost(Context context) {
return getServerIpAddress(getDevServerPort(context));
}
public static String getAdbReverseTcpCommand(Integer port) {
return "adb reverse tcp:" + port + " tcp:" + port;
}
public static String getAdbReverseTcpCommand(Context context) {
return getAdbReverseTcpCommand(getDevServerPort(context));
}
// WARNING(festevezga): This RN helper method has been copied to another FB-only target. Any
// changes should be applied to both.
public static String getFriendlyDeviceName() {
if (isRunningOnGenymotion()) {
// Genymotion already has a friendly name by default
return Build.MODEL;
} else {
return Build.MODEL + " - " + Build.VERSION.RELEASE + " - API " + Build.VERSION.SDK_INT;
}
}
/**
* Helper returning common metadata describing the React Native host, used to identify an
* inspector {@code HostTarget}. The returned mapping is a subset of {@code
* jsinspector_modern::HostTargetMetadata}.
*/
public static Map<String, String> getInspectorHostMetadata(@Nullable Context applicationContext) {
String appIdentifier = null;
String appDisplayName = null;
if (applicationContext != null) {
ApplicationInfo applicationInfo = applicationContext.getApplicationInfo();
int labelResourceId = applicationInfo.labelRes;
appIdentifier = applicationContext.getPackageName();
appDisplayName =
labelResourceId == 0
? applicationInfo.nonLocalizedLabel.toString()
: applicationContext.getString(labelResourceId);
}
return MapBuilder.<String, String>of(
"appDisplayName",
appDisplayName,
"appIdentifier",
appIdentifier,
"platform",
"android",
"deviceName",
Build.MODEL,
"reactNativeVersion",
getReactNativeVersionString());
}
private static String getReactNativeVersionString() {
Map<String, Object> version = ReactNativeVersion.VERSION;
return version.get("major")
+ "."
+ version.get("minor")
+ "."
+ version.get("patch")
+ (version.get("prerelease") != null ? "-" + version.get("prerelease") : "");
}
private static Integer getDevServerPort(Context context) {
Resources resources = context.getResources();
return resources.getInteger(R.integer.react_native_dev_server_port);
}
private static String getServerIpAddress(int port) {
// Since genymotion runs in vbox it use different hostname to refer to adb host.
// We detect whether app runs on genymotion and replace js bundle server hostname accordingly
String ipAddress;
String metroHostProp = getMetroHostPropValue();
if (!metroHostProp.equals("")) {
ipAddress = metroHostProp;
} else if (isRunningOnGenymotion()) {
ipAddress = GENYMOTION_LOCALHOST;
} else if (isRunningOnStockEmulator()) {
ipAddress = EMULATOR_LOCALHOST;
} else {
ipAddress = DEVICE_LOCALHOST;
}
return String.format(Locale.US, "%s:%d", ipAddress, port);
}
private static String metroHostPropValue = null;
private static synchronized String getMetroHostPropValue() {
if (metroHostPropValue != null) {
return metroHostPropValue;
}
Process process = null;
BufferedReader reader = null;
try {
process =
Runtime.getRuntime().exec(new String[] {"/system/bin/getprop", METRO_HOST_PROP_NAME});
reader =
new BufferedReader(
new InputStreamReader(process.getInputStream(), Charset.forName("UTF-8")));
String lastLine = "";
String line;
while ((line = reader.readLine()) != null) {
lastLine = line;
}
metroHostPropValue = lastLine;
} catch (Exception e) {
FLog.w(TAG, "Failed to query for metro.host prop:", e);
metroHostPropValue = "";
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (Exception exc) {
}
if (process != null) {
process.destroy();
}
}
return metroHostPropValue;
}
}
@@ -1,126 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.modules.systeminfo
import android.content.Context
import android.os.Build
import com.facebook.common.logging.FLog
import com.facebook.react.R
import java.io.BufferedReader
import java.io.InputStreamReader
import java.nio.charset.Charset
import java.util.Locale
public object AndroidInfoHelpers {
public const val EMULATOR_LOCALHOST: String = "10.0.2.2"
public const val GENYMOTION_LOCALHOST: String = "10.0.3.2"
public const val DEVICE_LOCALHOST: String = "localhost"
public const val METRO_HOST_PROP_NAME: String = "metro.host"
private val TAG = AndroidInfoHelpers::class.java.simpleName
private var metroHostPropValue: String? = null
private fun isRunningOnGenymotion(): Boolean = Build.FINGERPRINT.contains("vbox")
private fun isRunningOnStockEmulator(): Boolean =
Build.FINGERPRINT.contains("generic") || Build.FINGERPRINT.startsWith("google/sdk_gphone")
@JvmStatic public fun getServerHost(port: Int): String = getServerIpAddress(port)
@JvmStatic
public fun getServerHost(context: Context): String = getServerIpAddress(getDevServerPort(context))
@JvmStatic
public fun getAdbReverseTcpCommand(port: Int): String = "adb reverse tcp:$port tcp:$port"
@JvmStatic
public fun getAdbReverseTcpCommand(context: Context): String =
getAdbReverseTcpCommand(getDevServerPort(context))
@JvmStatic
public fun getFriendlyDeviceName(): String {
return if (isRunningOnGenymotion()) {
Build.MODEL
} else {
"${Build.MODEL} - ${Build.VERSION.RELEASE} - API ${Build.VERSION.SDK_INT}"
}
}
@JvmStatic
public fun getInspectorHostMetadata(applicationContext: Context?): Map<String, String?> {
var appIdentifier: String? = null
var appDisplayName: String? = null
if (applicationContext != null) {
val applicationInfo = applicationContext.applicationInfo
val labelResourceId = applicationInfo.labelRes
appIdentifier = applicationContext.packageName
appDisplayName =
if (labelResourceId == 0) {
applicationInfo.nonLocalizedLabel.toString()
} else {
applicationContext.getString(labelResourceId)
}
}
return mapOf(
"appDisplayName" to appDisplayName,
"appIdentifier" to appIdentifier,
"platform" to "android",
"deviceName" to Build.MODEL,
"reactNativeVersion" to getReactNativeVersionString())
}
private fun getReactNativeVersionString(): String {
val version = ReactNativeVersion.VERSION
return "${version["major"]}.${version["minor"]}.${version["patch"]}" +
(version["prerelease"]?.let { "-$it" } ?: "")
}
private fun getDevServerPort(context: Context): Int =
context.resources.getInteger(R.integer.react_native_dev_server_port)
private fun getServerIpAddress(port: Int): String {
val ipAddress: String =
when {
getMetroHostPropValue().isNotEmpty() -> getMetroHostPropValue()
isRunningOnGenymotion() -> GENYMOTION_LOCALHOST
isRunningOnStockEmulator() -> EMULATOR_LOCALHOST
else -> DEVICE_LOCALHOST
}
return String.format(Locale.US, "%s:%d", ipAddress, port)
}
@Synchronized
private fun getMetroHostPropValue(): String {
if (metroHostPropValue != null) {
return metroHostPropValue!!
}
var process: Process? = null
var reader: BufferedReader? = null
try {
process = Runtime.getRuntime().exec(arrayOf("/system/bin/getprop", METRO_HOST_PROP_NAME))
reader = BufferedReader(InputStreamReader(process.inputStream, Charset.forName("UTF-8")))
var lastLine = ""
var line: String?
while (reader.readLine().also { line = it } != null) {
lastLine = line ?: ""
}
metroHostPropValue = lastLine
} catch (e: Exception) {
FLog.w(TAG, "Failed to query for metro.host prop:", e)
metroHostPropValue = ""
} finally {
reader?.close()
process?.destroy()
}
return metroHostPropValue ?: ""
}
}
@@ -0,0 +1,104 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.modules.systeminfo;
import static android.content.Context.UI_MODE_SERVICE;
import android.annotation.SuppressLint;
import android.app.UiModeManager;
import android.content.res.Configuration;
import android.os.Build;
import android.provider.Settings.Secure;
import androidx.annotation.Nullable;
import com.facebook.fbreact.specs.NativePlatformConstantsAndroidSpec;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import java.util.HashMap;
import java.util.Map;
/** Module that exposes Android Constants to JS. */
@ReactModule(name = NativePlatformConstantsAndroidSpec.NAME)
@SuppressLint("HardwareIds")
public class AndroidInfoModule extends NativePlatformConstantsAndroidSpec implements TurboModule {
private static final String IS_TESTING = "IS_TESTING";
private static final String IS_DISABLE_ANIMATIONS = "IS_DISABLE_ANIMATIONS";
public AndroidInfoModule(ReactApplicationContext reactContext) {
super(reactContext);
}
/**
* See:
* https://developer.android.com/reference/android/app/UiModeManager.html#getCurrentModeType()
*/
private String uiMode() {
UiModeManager uiModeManager =
(UiModeManager) getReactApplicationContext().getSystemService(UI_MODE_SERVICE);
switch (uiModeManager.getCurrentModeType()) {
case Configuration.UI_MODE_TYPE_TELEVISION:
return "tv";
case Configuration.UI_MODE_TYPE_CAR:
return "car";
case Configuration.UI_MODE_TYPE_DESK:
return "desk";
case Configuration.UI_MODE_TYPE_WATCH:
return "watch";
case Configuration.UI_MODE_TYPE_VR_HEADSET:
return "vrheadset";
case Configuration.UI_MODE_TYPE_NORMAL:
return "normal";
default:
return "unknown";
}
}
@Override
public @Nullable Map<String, Object> getTypedExportedConstants() {
HashMap<String, Object> constants = new HashMap<>();
constants.put("Version", Build.VERSION.SDK_INT);
constants.put("Release", Build.VERSION.RELEASE);
constants.put("Serial", Build.SERIAL);
constants.put("Fingerprint", Build.FINGERPRINT);
constants.put("Model", Build.MODEL);
constants.put("Manufacturer", Build.MANUFACTURER);
constants.put("Brand", Build.BRAND);
if (ReactBuildConfig.DEBUG) {
constants.put(
"ServerHost",
AndroidInfoHelpers.getServerHost(getReactApplicationContext().getApplicationContext()));
}
constants.put(
"isTesting", "true".equals(System.getProperty(IS_TESTING)) || isRunningScreenshotTest());
String isDisableAnimations = System.getProperty(IS_DISABLE_ANIMATIONS);
if (isDisableAnimations != null) {
constants.put("isDisableAnimations", "true".equals(isDisableAnimations));
}
constants.put("reactNativeVersion", ReactNativeVersion.VERSION);
constants.put("uiMode", uiMode());
return constants;
}
@Override
public String getAndroidID() {
return Secure.getString(getReactApplicationContext().getContentResolver(), Secure.ANDROID_ID);
}
@Override
public void invalidate() {}
private Boolean isRunningScreenshotTest() {
try {
Class.forName("com.facebook.testing.react.screenshots.ReactAppScreenshotTestActivity");
return true;
} catch (ClassNotFoundException ignored) {
return false;
}
}
}
@@ -1,87 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.modules.systeminfo
import android.annotation.SuppressLint
import android.app.UiModeManager
import android.content.Context.UI_MODE_SERVICE
import android.content.res.Configuration
import android.os.Build
import android.provider.Settings.Secure
import com.facebook.fbreact.specs.NativePlatformConstantsAndroidSpec
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.common.build.ReactBuildConfig
import com.facebook.react.module.annotations.ReactModule
/** Module that exposes Android Constants to JS. */
@ReactModule(name = NativePlatformConstantsAndroidSpec.NAME)
@SuppressLint("HardwareIds")
@Suppress("DEPRECATION")
public class AndroidInfoModule(reactContext: ReactApplicationContext) :
NativePlatformConstantsAndroidSpec(reactContext) {
private companion object {
private const val IS_TESTING = "IS_TESTING"
private const val IS_DISABLE_ANIMATIONS = "IS_DISABLE_ANIMATIONS"
}
/**
* See:
* https://developer.android.com/reference/android/app/UiModeManager.html#getCurrentModeType()
*/
private fun uiMode(): String {
val uiModeManager = reactApplicationContext.getSystemService(UI_MODE_SERVICE) as UiModeManager
return when (uiModeManager.currentModeType) {
Configuration.UI_MODE_TYPE_TELEVISION -> "tv"
Configuration.UI_MODE_TYPE_CAR -> "car"
Configuration.UI_MODE_TYPE_DESK -> "desk"
Configuration.UI_MODE_TYPE_WATCH -> "watch"
Configuration.UI_MODE_TYPE_VR_HEADSET -> "vrheadset"
Configuration.UI_MODE_TYPE_NORMAL -> "normal"
else -> "unknown"
}
}
override fun getTypedExportedConstants(): Map<String, Any?> {
val constants = mutableMapOf<String, Any?>()
constants["Version"] = Build.VERSION.SDK_INT
constants["Release"] = Build.VERSION.RELEASE
constants["Serial"] = Build.SERIAL
constants["Fingerprint"] = Build.FINGERPRINT
constants["Model"] = Build.MODEL
constants["Manufacturer"] = Build.MANUFACTURER
constants["Brand"] = Build.BRAND
if (ReactBuildConfig.DEBUG) {
constants["ServerHost"] =
AndroidInfoHelpers.getServerHost(reactApplicationContext.applicationContext)
}
constants["isTesting"] = "true" == System.getProperty(IS_TESTING) || isRunningScreenshotTest()
val isDisableAnimations = System.getProperty(IS_DISABLE_ANIMATIONS)
if (isDisableAnimations != null) {
constants["isDisableAnimations"] = "true" == isDisableAnimations
}
constants["reactNativeVersion"] = ReactNativeVersion.VERSION
constants["uiMode"] = uiMode()
return constants
}
override fun getAndroidID(): String {
return Secure.getString(reactApplicationContext.contentResolver, Secure.ANDROID_ID)
}
override fun invalidate() {}
private fun isRunningScreenshotTest(): Boolean {
return try {
Class.forName("com.facebook.testing.react.screenshots.ReactAppScreenshotTestActivity")
true
} catch (ignored: ClassNotFoundException) {
false
}
}
}
@@ -194,7 +194,7 @@ public class ReactHostImpl implements ReactHost {
mUIExecutor = uiExecutor;
mMemoryPressureRouter = new MemoryPressureRouter(context);
mAllowPackagerServerAccess = allowPackagerServerAccess;
mUseDevSupport = useDevSupport;
mUseDevSupport = useDevSupport || ReactBuildConfig.UNSTABLE_ENABLE_FUSEBOX_RELEASE;
if (devSupportManagerFactory == null) {
devSupportManagerFactory = new DefaultDevSupportManagerFactory();
}
@@ -392,8 +392,8 @@ public class ReactHostImpl implements ReactHost {
Activity currentActivity = getCurrentActivity();
maybeEnableDevSupport(false);
if (currentActivity == activity) {
maybeEnableDevSupport(false);
moveToHostDestroy(getCurrentReactContext());
}
}
@@ -130,7 +130,9 @@ final class ReactInstance {
mQueueConfiguration.getNativeModulesQueueThread();
ReactChoreographer.initialize(AndroidChoreographerProvider.getInstance());
devSupportManager.startInspector();
if (useDevSupport) {
devSupportManager.startInspector();
}
JSTimerExecutor jsTimerExecutor = createJSTimerExecutor();
mJavaTimerManager =
@@ -298,10 +298,6 @@ public object BackgroundStyleApplicator {
val borderInsets = compositeBackgroundDrawable.borderInsets
val borderRadius = compositeBackgroundDrawable.borderRadius
/**
* z-ordering of user-provided shadow-list is opposite direction of LayerDrawable z-ordering
* https://drafts.csswg.org/css-backgrounds/#shadow-layers
*/
for (boxShadow in shadows.asReversed()) {
val offsetX = boxShadow.offsetX
val offsetY = boxShadow.offsetY
@@ -10,9 +10,6 @@ package com.facebook.react.uimanager
import android.annotation.TargetApi
import android.graphics.BlendMode
import android.os.Build
import android.view.ViewGroup
import androidx.core.view.children
import com.facebook.react.R
@TargetApi(29)
internal object BlendModeHelper {
@@ -44,8 +41,4 @@ internal object BlendModeHelper {
else -> throw IllegalArgumentException("Invalid mix-blend-mode name: $mixBlendMode")
}
}
@JvmStatic
public fun needsIsolatedLayer(view: ViewGroup): Boolean =
view.children.any { it.getTag(R.id.mix_blend_mode) != null }
}
@@ -29,7 +29,7 @@ internal object FilterHelper {
filters ?: return null
var chainedEffects: RenderEffect? = null
for (i in 0 until filters.size()) {
val filter = checkNotNull(filters.getMap(i)).entryIterator.next()
val filter = filters.getMap(i).entryIterator.next()
val filterName = filter.key
chainedEffects =
@@ -58,7 +58,7 @@ internal object FilterHelper {
// New ColorMatrix objects represent the identity matrix
val resultColorMatrix = ColorMatrix()
for (i in 0 until filters.size()) {
val filter = checkNotNull(filters.getMap(i)).entryIterator.next()
val filter = filters.getMap(i).entryIterator.next()
val filterName = filter.key
val amount = (filter.value as Double).toFloat()
@@ -88,7 +88,7 @@ internal object FilterHelper {
}
for (i in 0 until filters.size()) {
val filter = filters.getMap(i)!!.entryIterator.next()
val filter = filters.getMap(i).entryIterator.next()
val filterName = filter.key
if (filterName == "blur" || filterName == "dropShadow") {
return false
@@ -14,7 +14,6 @@ import androidx.annotation.Nullable;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.BaseJavaModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.mapbuffer.MapBuffer;
@@ -489,25 +488,4 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
mRecyclableViews = new HashMap<>();
}
}
/**
* @deprecated THIS PREFETCH METHOD IS EXPERIMENTAL, DO NOT USE IT FOR PRODUCTION CODE, MOST
* LIKELY IT WILL CHANGE OR BE REMOVED IN THE FUTURE.
* <p>Subclasses can override this method to implement custom resource prefetching for the
* ViewManager.
* @param reactContext {@link com.facebook.react.bridge.ReactContext} used for the view.
* @param surfaceId {@link int} surface ID
* @param reactTag reactTag that should be set as ID of the view instance
* @param params {@link MapBuffer} prefetch request params defined in C++
*/
@Deprecated
public void experimental_prefetchResource(
ReactContext reactContext, int surfaceId, int reactTag, MapBuffer params) {
return;
}
@Deprecated
protected boolean experimental_isPrefetchingEnabled() {
return ReactNativeFeatureFlags.enableImagePrefetchingAndroid();
}
}
@@ -10,6 +10,7 @@ package com.facebook.react.uimanager.annotations;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import androidx.annotation.Nullable;
import com.facebook.react.common.annotations.DeprecatedInNewArchitecture;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@@ -46,6 +47,7 @@ import java.lang.annotation.Target;
*/
@Retention(RUNTIME)
@Target(ElementType.METHOD)
@DeprecatedInNewArchitecture
public @interface ReactProp {
// Used as a default value for "customType" property as "null" is not allowed. Moreover, when this
@@ -10,6 +10,7 @@ package com.facebook.react.uimanager.annotations;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import androidx.annotation.Nullable;
import com.facebook.react.common.annotations.DeprecatedInNewArchitecture;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@@ -40,6 +41,7 @@ import java.lang.annotation.Target;
* provided as a default.
*/
@Retention(RUNTIME)
@DeprecatedInNewArchitecture
@Target(ElementType.METHOD)
public @interface ReactPropGroup {
@@ -7,6 +7,7 @@
package com.facebook.react.uimanager.annotations;
import com.facebook.react.common.annotations.DeprecatedInNewArchitecture;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
@@ -16,4 +17,5 @@ import java.lang.annotation.Target;
@Inherited
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
@DeprecatedInNewArchitecture
public @interface ReactPropertyHolder {}
@@ -7,6 +7,8 @@
package com.facebook.react.uimanager.debug
import com.facebook.react.common.annotations.DeprecatedInNewArchitecture
/**
* A listener that is notified about view hierarchy update events. This listener should only be used
* for debug purposes and should not affect application state.
@@ -14,8 +16,7 @@ package com.facebook.react.uimanager.debug
* NB: while [onViewHierarchyUpdateFinished] will always be called from the UI thread, there are no
* guarantees what thread onViewHierarchyUpdateEnqueued is called on.
*/
@Deprecated(
"NotThreadSafeViewHierarchyUpdateDebugListener will be deleted in the new architecture.")
@DeprecatedInNewArchitecture
internal interface NotThreadSafeViewHierarchyUpdateDebugListener {
/** Called when `UIManagerModule` enqueues a UI batch to be dispatched to the main thread. */
fun onViewHierarchyUpdateEnqueued()
@@ -21,7 +21,7 @@ import android.graphics.RectF
import android.graphics.Shader
import android.graphics.drawable.Drawable
import com.facebook.react.uimanager.PixelUtil.dpToPx
import com.facebook.react.uimanager.PixelUtil.pxToDp
import com.facebook.react.uimanager.PixelUtil.toDIPFromPixel
import com.facebook.react.uimanager.style.BackgroundImageLayer
import com.facebook.react.uimanager.style.BorderInsets
import com.facebook.react.uimanager.style.BorderRadiusStyle
@@ -184,7 +184,10 @@ internal class BackgroundDrawable(
computedBorderInsets = computeBorderInsets()
computedBorderRadius =
borderRadius?.resolve(
layoutDirection, context, bounds.width().pxToDp(), bounds.height().pxToDp())
layoutDirection,
context,
toDIPFromPixel(bounds.width().toFloat()),
toDIPFromPixel(bounds.height().toFloat()))
if (computedBorderRadius?.hasRoundedBorders() == true &&
computedBorderRadius?.isUniform() == false) {
@@ -24,8 +24,8 @@ import android.graphics.drawable.Drawable
import android.os.Build
import com.facebook.react.uimanager.FloatUtil.floatsEqual
import com.facebook.react.uimanager.LengthPercentage
import com.facebook.react.uimanager.PixelUtil
import com.facebook.react.uimanager.PixelUtil.dpToPx
import com.facebook.react.uimanager.PixelUtil.pxToDp
import com.facebook.react.uimanager.Spacing
import com.facebook.react.uimanager.style.BorderColors
import com.facebook.react.uimanager.style.BorderInsets
@@ -138,7 +138,7 @@ internal class BorderDrawable(
@Deprecated("Deprecated in Java")
override fun getOpacity(): Int {
val maxBorderAlpha =
maxOf(
minOf(
(Color.alpha(multiplyColorAlpha(computedBorderColors.left, borderAlpha))),
(Color.alpha(multiplyColorAlpha(computedBorderColors.top, borderAlpha))),
(Color.alpha(multiplyColorAlpha(computedBorderColors.right, borderAlpha))),
@@ -675,10 +675,10 @@ internal class BorderDrawable(
val borderWidth = computeBorderInsets()
// Clip border ONLY if at least one edge is non-transparent
if (Color.alpha(computedBorderColors.left) != 0 ||
Color.alpha(computedBorderColors.top) != 0 ||
Color.alpha(computedBorderColors.right) != 0 ||
// Clip border ONLY if its color is non transparent
if (Color.alpha(computedBorderColors.left) != 0 &&
Color.alpha(computedBorderColors.top) != 0 &&
Color.alpha(computedBorderColors.right) != 0 &&
Color.alpha(computedBorderColors.bottom) != 0) {
innerClipTempRectForBorderRadius?.top =
innerClipTempRectForBorderRadius?.top?.plus(borderWidth.top) ?: 0f
@@ -703,8 +703,8 @@ internal class BorderDrawable(
this.borderRadius?.resolve(
layoutDirection,
this.context,
outerClipTempRectForBorderRadius?.width()?.pxToDp() ?: 0f,
outerClipTempRectForBorderRadius?.height()?.pxToDp() ?: 0f,
PixelUtil.toDIPFromPixel(outerClipTempRectForBorderRadius?.width() ?: 0f),
PixelUtil.toDIPFromPixel(outerClipTempRectForBorderRadius?.height() ?: 0f),
)
val topLeftRadius = computedBorderRadius?.topLeft?.toPixelFromDIP() ?: CornerRadii(0f, 0f)
@@ -646,13 +646,13 @@ public class CSSBackgroundDrawable extends Drawable {
colorTop = colorBlockStart;
}
// Clip border ONLY if at least one edge is non-transparent
// Clip border ONLY if its color is non transparent
float pathAdjustment = 0f;
if (Color.alpha(colorLeft) != 0
|| Color.alpha(colorTop) != 0
|| Color.alpha(colorRight) != 0
|| Color.alpha(colorBottom) != 0
|| Color.alpha(borderColor) != 0) {
&& Color.alpha(colorTop) != 0
&& Color.alpha(colorRight) != 0
&& Color.alpha(colorBottom) != 0
&& Color.alpha(borderColor) != 0) {
mInnerClipTempRectForBorderRadius.top += borderWidth.top;
mInnerClipTempRectForBorderRadius.bottom -= borderWidth.bottom;
@@ -18,7 +18,7 @@ import android.graphics.PathEffect
import android.graphics.PixelFormat
import android.graphics.RectF
import android.graphics.drawable.Drawable
import com.facebook.react.uimanager.PixelUtil.pxToDp
import com.facebook.react.uimanager.PixelUtil.dpToPx
import com.facebook.react.uimanager.style.BorderRadiusStyle
import com.facebook.react.uimanager.style.ComputedBorderRadius
import com.facebook.react.uimanager.style.CornerRadii
@@ -123,7 +123,7 @@ internal class OutlineDrawable(
computedBorderRadius =
borderRadius?.resolve(
layoutDirection, context, bounds.width().pxToDp(), bounds.height().pxToDp())
layoutDirection, context, bounds.width().dpToPx(), bounds.height().dpToPx())
updateOutlineRect()
if (computedBorderRadius != null && computedBorderRadius?.hasRoundedBorders() == true) {
@@ -107,11 +107,11 @@ public data class BorderRadiusStyle(
width: Float,
height: Float,
): ComputedBorderRadius {
val zeroRadii = CornerRadii(0f, 0f)
val zeroRadii: CornerRadii = CornerRadii(0f, 0f)
return when (layoutDirection) {
LayoutDirection.LTR ->
ensureNoOverlap(
ComputedBorderRadius(
topLeft =
(startStart ?: topStart ?: topLeft ?: uniform)?.resolve(width, height)
?: zeroRadii,
@@ -123,12 +123,10 @@ public data class BorderRadiusStyle(
bottomRight =
(endEnd ?: bottomEnd ?: bottomRight ?: uniform)?.resolve(width, height)
?: zeroRadii,
width = width,
height = height,
)
LayoutDirection.RTL ->
if (I18nUtil.instance.doLeftAndRightSwapInRTL(context)) {
ensureNoOverlap(
ComputedBorderRadius(
topLeft =
(endStart ?: topEnd ?: topRight ?: uniform)?.resolve(width, height)
?: zeroRadii,
@@ -141,11 +139,9 @@ public data class BorderRadiusStyle(
bottomRight =
(startEnd ?: bottomEnd ?: bottomLeft ?: uniform)?.resolve(width, height)
?: zeroRadii,
width = width,
height = height,
)
} else {
ensureNoOverlap(
ComputedBorderRadius(
topLeft =
(endStart ?: topEnd ?: topLeft ?: uniform)?.resolve(width, height) ?: zeroRadii,
topRight =
@@ -157,53 +153,9 @@ public data class BorderRadiusStyle(
bottomRight =
(startEnd ?: bottomEnd ?: bottomRight ?: uniform)?.resolve(width, height)
?: zeroRadii,
width = width,
height = height,
)
}
else -> throw IllegalArgumentException("Expected?.resolved layout direction")
}
}
/**
* "Corner curves must not overlap: When the sum of any two adjacent border radii exceeds the size
* of the border box, UAs must proportionally reduce the used values of all border radii until
* none of them overlap." Source: https://www.w3.org/TR/css-backgrounds-3/#corner-overlap
*/
private fun ensureNoOverlap(
topLeft: CornerRadii,
topRight: CornerRadii,
bottomLeft: CornerRadii,
bottomRight: CornerRadii,
width: Float,
height: Float
): ComputedBorderRadius {
val leftEdgeRadii = topLeft.vertical + bottomLeft.vertical
val topEdgeRadii = topLeft.horizontal + topRight.horizontal
val rightEdgeRadii = topRight.vertical + bottomRight.vertical
val bottomEdgeRadii = bottomLeft.horizontal + bottomRight.horizontal
val leftEdgeRadiiScale = if (leftEdgeRadii > 0) minOf(height / leftEdgeRadii, 1f) else 0f
val topEdgeRadiiScale = if (topEdgeRadii > 0) minOf(width / topEdgeRadii, 1f) else 0f
val rightEdgeRadiiScale = if (rightEdgeRadii > 0) minOf(height / rightEdgeRadii, 1f) else 0f
val bottomEdgeRadiiScale = if (bottomEdgeRadii > 0) minOf(width / bottomEdgeRadii, 1f) else 0f
return ComputedBorderRadius(
topLeft =
CornerRadii(
topLeft.horizontal * minOf(topEdgeRadiiScale, leftEdgeRadiiScale),
topLeft.vertical * minOf(topEdgeRadiiScale, leftEdgeRadiiScale)),
topRight =
CornerRadii(
topRight.horizontal * minOf(rightEdgeRadiiScale, topEdgeRadiiScale),
topRight.vertical * minOf(rightEdgeRadiiScale, topEdgeRadiiScale)),
bottomLeft =
CornerRadii(
bottomLeft.horizontal * minOf(bottomEdgeRadiiScale, leftEdgeRadiiScale),
bottomLeft.vertical * minOf(bottomEdgeRadiiScale, leftEdgeRadiiScale)),
bottomRight =
CornerRadii(
bottomRight.horizontal * minOf(bottomEdgeRadiiScale, rightEdgeRadiiScale),
bottomRight.vertical * minOf(bottomEdgeRadiiScale, rightEdgeRadiiScale)))
}
}
@@ -25,8 +25,8 @@ public data class BoxShadow(
) {
public companion object {
@JvmStatic
public fun parse(boxShadow: ReadableMap?, context: Context): BoxShadow? {
if (boxShadow == null || !(boxShadow.hasKey("offsetX") && boxShadow.hasKey("offsetY"))) {
public fun parse(boxShadow: ReadableMap, context: Context): BoxShadow? {
if (!(boxShadow.hasKey("offsetX") && boxShadow.hasKey("offsetY"))) {
return null
}
@@ -45,7 +45,7 @@ internal class Gradient(gradient: ReadableMap?, context: Context) {
val positions = FloatArray(size)
for (i in 0 until size) {
val colorStop = colorStops.getMap(i) ?: continue
val colorStop = colorStops.getMap(i)
colors[i] =
if (colorStop.getType("color") == ReadableType.Map) {
ColorPropConverter.getColor(colorStop.getMap("color"), context)
@@ -24,7 +24,7 @@ public object JSStackTrace {
public fun format(message: String, stack: ReadableArray): String {
val stringBuilder = StringBuilder(message).append(", stack:\n")
for (i in 0 until stack.size()) {
val frame = stack.getMap(i) ?: continue
val frame = stack.getMap(i)
stringBuilder.append(frame.getString(METHOD_NAME_KEY)).append("@").append(parseFileId(frame))
if (frame.hasKey(LINE_NUMBER_KEY) &&
!frame.isNull(LINE_NUMBER_KEY) &&
@@ -44,12 +44,16 @@ public class DebuggingOverlayManager :
}
public override fun highlightTraceUpdates(view: DebuggingOverlay, args: ReadableArray?): Unit {
val providedTraceUpdates = args?.getArray(0) ?: return
if (args == null) {
return
}
val providedTraceUpdates = args.getArray(0)
val formattedTraceUpdates = mutableListOf<TraceUpdate>()
var successfullyParsedPayload = true
for (i in 0 until providedTraceUpdates.size()) {
val traceUpdate = providedTraceUpdates.getMap(i) ?: continue
val traceUpdate = providedTraceUpdates.getMap(i)
val serializedRectangle = traceUpdate.getMap("rectangle")
if (serializedRectangle == null) {
ReactSoftExceptionLogger.logSoftException(
@@ -94,12 +98,17 @@ public class DebuggingOverlayManager :
}
public override fun highlightElements(view: DebuggingOverlay, args: ReadableArray?): Unit {
val providedElements = args?.getArray(0) ?: return
if (args == null) {
return
}
val providedElements = args.getArray(0)
val elementsRectangles = mutableListOf<RectF>()
var successfullyParsedPayload = true
for (i in 0 until providedElements.size()) {
val element = providedElements.getMap(i) ?: continue
val element = providedElements.getMap(i)
try {
val left = element.getDouble("x").toFloat()
val top = element.getDouble("y").toFloat()
@@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
@file:Suppress("DEPRECATION") // GenericDraweeView is deprecated
@file:Suppress("DEPRECATION") // As we depend on ReactFeatureFlags still
package com.facebook.react.views.image
@@ -270,7 +270,7 @@ public class ReactImageView(
tmpSources.add(getTransparentBitmapImageSource(context))
} else if (sources.size() == 1) {
// Optimize for the case where we have just one uri, case in which we don't need the sizes
val source = checkNotNull(sources.getMap(0))
val source = sources.getMap(0)
val cacheControl = computeCacheControl(source.getString("cache"))
var imageSource = ImageSource(context, source.getString("uri"), cacheControl = cacheControl)
if (Uri.EMPTY == imageSource.uri) {
@@ -280,7 +280,7 @@ public class ReactImageView(
tmpSources.add(imageSource)
} else {
for (idx in 0 until sources.size()) {
val source = sources.getMap(idx) ?: continue
val source = sources.getMap(idx)
val cacheControl = computeCacheControl(source.getString("cache"))
var imageSource =
ImageSource(
@@ -14,7 +14,7 @@ public class ShadowStyleSpan(
private val dx: Float,
private val dy: Float,
private val radius: Float,
public val color: Int
private val color: Int
) : CharacterStyle(), ReactSpan {
public override fun updateDrawState(textPaint: TextPaint) {
textPaint.setShadowLayer(radius, dx, dy, color)
@@ -15,14 +15,15 @@ import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewStructure;
import android.view.animation.Animation;
import androidx.annotation.Nullable;
@@ -33,12 +34,12 @@ import com.facebook.react.R;
import com.facebook.react.bridge.ReactNoCrashSoftException;
import com.facebook.react.bridge.ReactSoftExceptionLogger;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.touch.OnInterceptTouchEventListener;
import com.facebook.react.touch.ReactHitSlopView;
import com.facebook.react.touch.ReactInterceptingViewGroup;
import com.facebook.react.uimanager.BackgroundStyleApplicator;
import com.facebook.react.uimanager.BlendModeHelper;
import com.facebook.react.uimanager.LengthPercentage;
import com.facebook.react.uimanager.LengthPercentageType;
import com.facebook.react.uimanager.MeasureSpecAssertions;
@@ -53,12 +54,11 @@ import com.facebook.react.uimanager.ReactZIndexedViewGroup;
import com.facebook.react.uimanager.ViewGroupDrawingOrderHelper;
import com.facebook.react.uimanager.common.UIManagerType;
import com.facebook.react.uimanager.common.ViewUtil;
import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable;
import com.facebook.react.uimanager.style.BorderRadiusProp;
import com.facebook.react.uimanager.style.BorderStyle;
import com.facebook.react.uimanager.style.LogicalEdge;
import com.facebook.react.uimanager.style.Overflow;
import java.util.HashSet;
import java.util.Set;
/**
* Backing for a React View. Has support for borders, but since borders aren't common, lazy
@@ -74,6 +74,7 @@ public class ReactViewGroup extends ViewGroup
ReactOverflowViewWithInset {
private static final int ARRAY_CAPACITY_INCREMENT = 12;
private static final int DEFAULT_BACKGROUND_COLOR = Color.TRANSPARENT;
private static final LayoutParams sDefaultLayoutParam = new ViewGroup.LayoutParams(0, 0);
private final Rect mOverflowInset = new Rect();
@@ -130,11 +131,13 @@ public class ReactViewGroup extends ViewGroup
private @Nullable Rect mClippingRect;
private @Nullable Rect mHitSlopRect;
private Overflow mOverflow;
private PointerEvents mPointerEvents = PointerEvents.AUTO;
private PointerEvents mPointerEvents;
private @Nullable ChildrenLayoutChangeListener mChildrenLayoutChangeListener;
private @Nullable CSSBackgroundDrawable mCSSBackgroundDrawable;
private @Nullable OnInterceptTouchEventListener mOnInterceptTouchEventListener;
private boolean mNeedsOffscreenAlphaCompositing;
private @Nullable ViewGroupDrawingOrderHelper mDrawingOrderHelper;
private @Nullable Path mPath;
private float mBackfaceOpacity;
private String mBackfaceVisibility;
@@ -165,9 +168,11 @@ public class ReactViewGroup extends ViewGroup
mOverflow = Overflow.VISIBLE;
mPointerEvents = PointerEvents.AUTO;
mChildrenLayoutChangeListener = null;
mCSSBackgroundDrawable = null;
mOnInterceptTouchEventListener = null;
mNeedsOffscreenAlphaCompositing = false;
mDrawingOrderHelper = null;
mPath = null;
mBackfaceOpacity = 1.f;
mBackfaceVisibility = "visible";
}
@@ -261,7 +266,7 @@ public class ReactViewGroup extends ViewGroup
}
@Override
public boolean onTouchEvent(MotionEvent event) {
public boolean onTouchEvent(MotionEvent ev) {
// We do not accept the touch event if this view is not supposed to receive it.
if (!PointerEvents.canBeTouchTarget(mPointerEvents)) {
return false;
@@ -317,7 +322,7 @@ public class ReactViewGroup extends ViewGroup
}
/**
* @deprecated Use {@link #setBorderRadius(BorderRadiusProp, LengthPercentage)} instead.
* @deprecated Use {@link #setBorderRadius(BorderRadiusProp, Float)} instead.
*/
@Deprecated(since = "0.75.0", forRemoval = true)
public void setBorderRadius(float borderRadius) {
@@ -325,7 +330,7 @@ public class ReactViewGroup extends ViewGroup
}
/**
* @deprecated Use {@link #setBorderRadius(BorderRadiusProp, LengthPercentage)} instead.
* @deprecated Use {@link #setBorderRadius(BorderRadiusProp, Float)} instead.
*/
@Deprecated(since = "0.75.0", forRemoval = true)
public void setBorderRadius(float borderRadius, int position) {
@@ -412,13 +417,6 @@ public class ReactViewGroup extends ViewGroup
try {
updateSubviewClipStatus(clippingRect, i, clippedSoFar);
} catch (IndexOutOfBoundsException e) {
int realClippedSoFar = 0;
Set<View> uniqueViews = new HashSet<>();
for (int j = 0; j < i; j++) {
realClippedSoFar += isViewClipped(mAllChildren[j]) ? 1 : 0;
uniqueViews.add(mAllChildren[j]);
}
throw new IllegalStateException(
"Invalid clipping state. i="
+ i
@@ -429,14 +427,10 @@ public class ReactViewGroup extends ViewGroup
+ " allChildrenCount="
+ mAllChildrenCount
+ " recycleCount="
+ mRecycleCount
+ " realClippedSoFar="
+ realClippedSoFar
+ " uniqueViewsCount="
+ uniqueViews.size(),
+ mRecycleCount,
e);
}
if (isViewClipped(mAllChildren[i])) {
if (mAllChildren[i].getParent() == null) {
clippedSoFar++;
}
}
@@ -458,15 +452,13 @@ public class ReactViewGroup extends ViewGroup
// it won't be size and located properly.
Animation animation = child.getAnimation();
boolean isAnimating = animation != null && !animation.hasEnded();
if (!intersects && !isViewClipped(child) && !isAnimating) {
if (!intersects && child.getParent() != null && !isAnimating) {
// We can try saving on invalidate call here as the view that we remove is out of visible area
// therefore invalidation is not necessary.
removeViewInLayout(child);
needUpdateClippingRecursive = true;
} else if (intersects && isViewClipped(child)) {
int adjustedIdx = idx - clippedSoFar;
Assertions.assertCondition(adjustedIdx >= 0);
addViewInLayout(child, adjustedIdx, sDefaultLayoutParam, true);
} else if (intersects && child.getParent() == null) {
addViewInLayout(child, idx - clippedSoFar, sDefaultLayoutParam, true);
invalidate();
needUpdateClippingRecursive = true;
} else if (intersects) {
@@ -497,7 +489,7 @@ public class ReactViewGroup extends ViewGroup
subview.getLeft(), subview.getTop(), subview.getRight(), subview.getBottom());
// If it was intersecting before, should be attached to the parent
boolean oldIntersects = !isViewClipped(subview);
boolean oldIntersects = (subview.getParent() != null);
if (intersects != oldIntersects) {
int clippedSoFar = 0;
@@ -506,13 +498,18 @@ public class ReactViewGroup extends ViewGroup
updateSubviewClipStatus(mClippingRect, i, clippedSoFar);
break;
}
if (isViewClipped(mAllChildren[i])) {
if (mAllChildren[i].getParent() == null) {
clippedSoFar++;
}
}
}
}
@Override
public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset) {
return super.getChildVisibleRect(child, r, offset);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
@@ -538,33 +535,83 @@ public class ReactViewGroup extends ViewGroup
return ViewUtil.getUIManagerType(getId()) == UIManagerType.FABRIC;
}
@Override
public void onViewAdded(View child) {
private void handleAddView(View view) {
UiThreadUtil.assertOnUiThread();
if (!customDrawOrderDisabled()) {
getDrawingOrderHelper().handleAddView(child);
getDrawingOrderHelper().handleAddView(view);
setChildrenDrawingOrderEnabled(getDrawingOrderHelper().shouldEnableCustomDrawingOrder());
} else {
setChildrenDrawingOrderEnabled(false);
}
super.onViewAdded(child);
}
private void handleRemoveView(@Nullable View view) {
UiThreadUtil.assertOnUiThread();
if (!customDrawOrderDisabled()) {
if (indexOfChild(view) == -1) {
return;
}
getDrawingOrderHelper().handleRemoveView(view);
setChildrenDrawingOrderEnabled(getDrawingOrderHelper().shouldEnableCustomDrawingOrder());
} else {
setChildrenDrawingOrderEnabled(false);
}
}
private void handleRemoveViews(int start, int count) {
int endIndex = start + count;
for (int index = start; index < endIndex; index++) {
if (index < getChildCount()) {
handleRemoveView(getChildAt(index));
}
}
}
@Override
public void onViewRemoved(View child) {
UiThreadUtil.assertOnUiThread();
public void addView(View child, int index, @Nullable ViewGroup.LayoutParams params) {
// This will get called for every overload of addView so there is not need to override every
// method.
handleAddView(child);
super.addView(child, index, params);
}
if (!customDrawOrderDisabled()) {
if (indexOfChild(child) == -1) {
return;
}
getDrawingOrderHelper().handleRemoveView(child);
setChildrenDrawingOrderEnabled(getDrawingOrderHelper().shouldEnableCustomDrawingOrder());
} else {
setChildrenDrawingOrderEnabled(false);
}
super.onViewRemoved(child);
@Override
protected boolean addViewInLayout(
View child, int index, LayoutParams params, boolean preventRequestLayout) {
handleAddView(child);
return super.addViewInLayout(child, index, params, preventRequestLayout);
}
@Override
public void removeView(@Nullable View view) {
handleRemoveView(view);
super.removeView(view);
}
@Override
public void removeViewAt(int index) {
handleRemoveView(getChildAt(index));
super.removeViewAt(index);
}
@Override
public void removeViewInLayout(View view) {
handleRemoveView(view);
super.removeViewInLayout(view);
}
@Override
public void removeViewsInLayout(int start, int count) {
handleRemoveViews(start, count);
super.removeViewsInLayout(start, count);
}
@Override
public void removeViews(int start, int count) {
handleRemoveViews(start, count);
super.removeViews(start, count);
}
@Override
@@ -638,19 +685,18 @@ public class ReactViewGroup extends ViewGroup
/*package*/ void addViewWithSubviewClippingEnabled(
final View child, int index, ViewGroup.LayoutParams params) {
Assertions.assertCondition(mRemoveClippedSubviews);
Assertions.assertNotNull(mClippingRect);
Assertions.assertNotNull(mAllChildren);
addInArray(child, index);
// we add view as "clipped" and then run {@link #updateSubviewClipStatus} to conditionally
// attach it
Rect clippingRect = Assertions.assertNotNull(mClippingRect);
View[] childArray = Assertions.assertNotNull(mAllChildren);
int clippedSoFar = 0;
for (int i = 0; i < index; i++) {
if (isViewClipped(childArray[i])) {
if (mAllChildren[i].getParent() == null) {
clippedSoFar++;
}
}
updateSubviewClipStatus(clippingRect, index, clippedSoFar);
updateSubviewClipStatus(mClippingRect, index, clippedSoFar);
child.addOnLayoutChangeListener(mChildrenLayoutChangeListener);
if (child instanceof ReactClippingProhibitedView) {
@@ -682,13 +728,13 @@ public class ReactViewGroup extends ViewGroup
Assertions.assertCondition(mRemoveClippedSubviews);
Assertions.assertNotNull(mClippingRect);
View[] childArray = Assertions.assertNotNull(mAllChildren);
Assertions.assertNotNull(mAllChildren);
view.removeOnLayoutChangeListener(mChildrenLayoutChangeListener);
int index = indexOfChildInAllChildren(view);
if (!isViewClipped(childArray[index])) {
if (mAllChildren[index].getParent() != null) {
int clippedSoFar = 0;
for (int i = 0; i < index; i++) {
if (isViewClipped(childArray[i])) {
if (mAllChildren[i].getParent() == null) {
clippedSoFar++;
}
}
@@ -699,32 +745,19 @@ public class ReactViewGroup extends ViewGroup
/*package*/ void removeAllViewsWithSubviewClippingEnabled() {
Assertions.assertCondition(mRemoveClippedSubviews);
View[] childArray = Assertions.assertNotNull(mAllChildren);
Assertions.assertNotNull(mAllChildren);
for (int i = 0; i < mAllChildrenCount; i++) {
childArray[i].removeOnLayoutChangeListener(mChildrenLayoutChangeListener);
mAllChildren[i].removeOnLayoutChangeListener(mChildrenLayoutChangeListener);
}
removeAllViewsInLayout();
mAllChildrenCount = 0;
}
/**
* @return {@code true} if the view has been removed from the ViewGroup.
*/
private boolean isViewClipped(View view) {
ViewParent parent = view.getParent();
if (parent == null) {
return true;
} else {
Assertions.assertCondition(parent == this);
return false;
}
}
private int indexOfChildInAllChildren(View child) {
final int count = mAllChildrenCount;
final View[] childArray = Assertions.assertNotNull(mAllChildren);
final View[] children = Assertions.assertNotNull(mAllChildren);
for (int i = 0; i < count; i++) {
if (childArray[i] == child) {
if (children[i] == child) {
return i;
}
}
@@ -732,26 +765,26 @@ public class ReactViewGroup extends ViewGroup
}
private void addInArray(View child, int index) {
View[] childArray = Assertions.assertNotNull(mAllChildren);
View[] children = Assertions.assertNotNull(mAllChildren);
final int count = mAllChildrenCount;
final int size = childArray.length;
final int size = children.length;
if (index == count) {
if (size == count) {
mAllChildren = new View[size + ARRAY_CAPACITY_INCREMENT];
System.arraycopy(childArray, 0, mAllChildren, 0, size);
childArray = mAllChildren;
System.arraycopy(children, 0, mAllChildren, 0, size);
children = mAllChildren;
}
childArray[mAllChildrenCount++] = child;
children[mAllChildrenCount++] = child;
} else if (index < count) {
if (size == count) {
mAllChildren = new View[size + ARRAY_CAPACITY_INCREMENT];
System.arraycopy(childArray, 0, mAllChildren, 0, index);
System.arraycopy(childArray, index, mAllChildren, index + 1, count - index);
childArray = mAllChildren;
System.arraycopy(children, 0, mAllChildren, 0, index);
System.arraycopy(children, index, mAllChildren, index + 1, count - index);
children = mAllChildren;
} else {
System.arraycopy(childArray, index, childArray, index + 1, count - index);
System.arraycopy(children, index, children, index + 1, count - index);
}
childArray[index] = child;
children[index] = child;
mAllChildrenCount++;
} else {
throw new IndexOutOfBoundsException("index=" + index + " count=" + count);
@@ -759,18 +792,34 @@ public class ReactViewGroup extends ViewGroup
}
private void removeFromArray(int index) {
final View[] childArray = Assertions.assertNotNull(mAllChildren);
final View[] children = Assertions.assertNotNull(mAllChildren);
final int count = mAllChildrenCount;
if (index == count - 1) {
childArray[--mAllChildrenCount] = null;
children[--mAllChildrenCount] = null;
} else if (index >= 0 && index < count) {
System.arraycopy(childArray, index + 1, childArray, index, count - index - 1);
childArray[--mAllChildrenCount] = null;
System.arraycopy(children, index + 1, children, index, count - index - 1);
children[--mAllChildrenCount] = null;
} else {
throw new IndexOutOfBoundsException();
}
}
private boolean needsIsolatedLayer() {
for (int i = 0; i < getChildCount(); i++) {
if (getChildAt(i).getTag(R.id.mix_blend_mode) != null) {
return true;
}
}
return false;
}
@VisibleForTesting
public int getBackgroundColor() {
@Nullable Integer color = BackgroundStyleApplicator.getBackgroundColor(this);
return color == null ? DEFAULT_BACKGROUND_COLOR : color;
}
@Override
public @Nullable Rect getHitSlopRect() {
return mHitSlopRect;
@@ -807,7 +856,7 @@ public class ReactViewGroup extends ViewGroup
@Override
public void setOverflowInset(int left, int top, int right, int bottom) {
if (BlendModeHelper.needsIsolatedLayer(this)
if (needsIsolatedLayer()
&& (mOverflowInset.left != left
|| mOverflowInset.top != top
|| mOverflowInset.right != right
@@ -837,7 +886,7 @@ public class ReactViewGroup extends ViewGroup
public void draw(Canvas canvas) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
&& ViewUtil.getUIManagerType(this) == UIManagerType.FABRIC
&& BlendModeHelper.needsIsolatedLayer(this)) {
&& needsIsolatedLayer()) {
// Check if the view is a stacking context and has children, if it does, do the rendering
// offscreen and then composite back. This follows the idea of group isolation on blending
@@ -873,9 +922,7 @@ public class ReactViewGroup extends ViewGroup
}
BlendMode mixBlendMode = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
&& ViewUtil.getUIManagerType(this) == UIManagerType.FABRIC
&& BlendModeHelper.needsIsolatedLayer(this)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && needsIsolatedLayer()) {
mixBlendMode = (BlendMode) child.getTag(R.id.mix_blend_mode);
if (mixBlendMode != null) {
Paint p = new Paint();
@@ -74,6 +74,9 @@ public class YogaNative {
static native void jni_YGNodeStyleSetFlexBasisJNI(long nativePointer, float flexBasis);
static native void jni_YGNodeStyleSetFlexBasisPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetFlexBasisAutoJNI(long nativePointer);
static native void jni_YGNodeStyleSetFlexBasisMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetFlexBasisFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetFlexBasisStretchJNI(long nativePointer);
static native long jni_YGNodeStyleGetMarginJNI(long nativePointer, int edge);
static native void jni_YGNodeStyleSetMarginJNI(long nativePointer, int edge, float margin);
static native void jni_YGNodeStyleSetMarginPercentJNI(long nativePointer, int edge, float percent);
@@ -91,22 +94,40 @@ public class YogaNative {
static native void jni_YGNodeStyleSetWidthJNI(long nativePointer, float width);
static native void jni_YGNodeStyleSetWidthPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetWidthAutoJNI(long nativePointer);
static native void jni_YGNodeStyleSetWidthMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetWidthFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetWidthStretchJNI(long nativePointer);
static native long jni_YGNodeStyleGetHeightJNI(long nativePointer);
static native void jni_YGNodeStyleSetHeightJNI(long nativePointer, float height);
static native void jni_YGNodeStyleSetHeightPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetHeightAutoJNI(long nativePointer);
static native void jni_YGNodeStyleSetHeightMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetHeightFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetHeightStretchJNI(long nativePointer);
static native long jni_YGNodeStyleGetMinWidthJNI(long nativePointer);
static native void jni_YGNodeStyleSetMinWidthJNI(long nativePointer, float minWidth);
static native void jni_YGNodeStyleSetMinWidthPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetMinWidthMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMinWidthFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMinWidthStretchJNI(long nativePointer);
static native long jni_YGNodeStyleGetMinHeightJNI(long nativePointer);
static native void jni_YGNodeStyleSetMinHeightJNI(long nativePointer, float minHeight);
static native void jni_YGNodeStyleSetMinHeightPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetMinHeightMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMinHeightFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMinHeightStretchJNI(long nativePointer);
static native long jni_YGNodeStyleGetMaxWidthJNI(long nativePointer);
static native void jni_YGNodeStyleSetMaxWidthJNI(long nativePointer, float maxWidth);
static native void jni_YGNodeStyleSetMaxWidthPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetMaxWidthMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMaxWidthFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMaxWidthStretchJNI(long nativePointer);
static native long jni_YGNodeStyleGetMaxHeightJNI(long nativePointer);
static native void jni_YGNodeStyleSetMaxHeightJNI(long nativePointer, float maxheight);
static native void jni_YGNodeStyleSetMaxHeightPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetMaxHeightMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMaxHeightFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMaxHeightStretchJNI(long nativePointer);
static native float jni_YGNodeStyleGetAspectRatioJNI(long nativePointer);
static native void jni_YGNodeStyleSetAspectRatioJNI(long nativePointer, float aspectRatio);
static native float jni_YGNodeStyleGetGapJNI(long nativePointer, int gutter);
@@ -124,6 +124,12 @@ public abstract class YogaNode implements YogaProps {
public abstract void setFlexBasisAuto();
public abstract void setFlexBasisMaxContent();
public abstract void setFlexBasisFitContent();
public abstract void setFlexBasisStretch();
public abstract YogaValue getMargin(YogaEdge edge);
public abstract void setMargin(YogaEdge edge, float margin);
@@ -158,6 +164,12 @@ public abstract class YogaNode implements YogaProps {
public abstract void setWidthAuto();
public abstract void setWidthMaxContent();
public abstract void setWidthFitContent();
public abstract void setWidthStretch();
public abstract YogaValue getHeight();
public abstract void setHeight(float height);
@@ -166,30 +178,60 @@ public abstract class YogaNode implements YogaProps {
public abstract void setHeightAuto();
public abstract void setHeightMaxContent();
public abstract void setHeightFitContent();
public abstract void setHeightStretch();
public abstract YogaValue getMinWidth();
public abstract void setMinWidth(float minWidth);
public abstract void setMinWidthPercent(float percent);
public abstract void setMinWidthMaxContent();
public abstract void setMinWidthFitContent();
public abstract void setMinWidthStretch();
public abstract YogaValue getMinHeight();
public abstract void setMinHeight(float minHeight);
public abstract void setMinHeightPercent(float percent);
public abstract void setMinHeightMaxContent();
public abstract void setMinHeightFitContent();
public abstract void setMinHeightStretch();
public abstract YogaValue getMaxWidth();
public abstract void setMaxWidth(float maxWidth);
public abstract void setMaxWidthPercent(float percent);
public abstract void setMaxWidthMaxContent();
public abstract void setMaxWidthFitContent();
public abstract void setMaxWidthStretch();
public abstract YogaValue getMaxHeight();
public abstract void setMaxHeight(float maxheight);
public abstract void setMaxHeightPercent(float percent);
public abstract void setMaxHeightMaxContent();
public abstract void setMaxHeightFitContent();
public abstract void setMaxHeightStretch();
public abstract float getAspectRatio();
public abstract void setAspectRatio(float aspectRatio);
@@ -373,6 +373,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetFlexBasisAutoJNI(mNativePointer);
}
public void setFlexBasisMaxContent() {
YogaNative.jni_YGNodeStyleSetFlexBasisMaxContentJNI(mNativePointer);
}
public void setFlexBasisFitContent() {
YogaNative.jni_YGNodeStyleSetFlexBasisFitContentJNI(mNativePointer);
}
public void setFlexBasisStretch() {
YogaNative.jni_YGNodeStyleSetFlexBasisStretchJNI(mNativePointer);
}
public YogaValue getMargin(YogaEdge edge) {
return valueFromLong(YogaNative.jni_YGNodeStyleGetMarginJNI(mNativePointer, edge.intValue()));
}
@@ -441,6 +453,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetWidthAutoJNI(mNativePointer);
}
public void setWidthMaxContent() {
YogaNative.jni_YGNodeStyleSetWidthMaxContentJNI(mNativePointer);
}
public void setWidthFitContent() {
YogaNative.jni_YGNodeStyleSetWidthFitContentJNI(mNativePointer);
}
public void setWidthStretch() {
YogaNative.jni_YGNodeStyleSetWidthStretchJNI(mNativePointer);
}
public YogaValue getHeight() {
return valueFromLong(YogaNative.jni_YGNodeStyleGetHeightJNI(mNativePointer));
}
@@ -457,6 +481,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetHeightAutoJNI(mNativePointer);
}
public void setHeightMaxContent() {
YogaNative.jni_YGNodeStyleSetHeightMaxContentJNI(mNativePointer);
}
public void setHeightFitContent() {
YogaNative.jni_YGNodeStyleSetHeightFitContentJNI(mNativePointer);
}
public void setHeightStretch() {
YogaNative.jni_YGNodeStyleSetHeightStretchJNI(mNativePointer);
}
public YogaValue getMinWidth() {
return valueFromLong(YogaNative.jni_YGNodeStyleGetMinWidthJNI(mNativePointer));
}
@@ -469,6 +505,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetMinWidthPercentJNI(mNativePointer, percent);
}
public void setMinWidthMaxContent() {
YogaNative.jni_YGNodeStyleSetMinWidthMaxContentJNI(mNativePointer);
}
public void setMinWidthFitContent() {
YogaNative.jni_YGNodeStyleSetMinWidthFitContentJNI(mNativePointer);
}
public void setMinWidthStretch() {
YogaNative.jni_YGNodeStyleSetMinWidthStretchJNI(mNativePointer);
}
public YogaValue getMinHeight() {
return valueFromLong(YogaNative.jni_YGNodeStyleGetMinHeightJNI(mNativePointer));
}
@@ -481,6 +529,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetMinHeightPercentJNI(mNativePointer, percent);
}
public void setMinHeightMaxContent() {
YogaNative.jni_YGNodeStyleSetMinHeightMaxContentJNI(mNativePointer);
}
public void setMinHeightFitContent() {
YogaNative.jni_YGNodeStyleSetMinHeightFitContentJNI(mNativePointer);
}
public void setMinHeightStretch() {
YogaNative.jni_YGNodeStyleSetMinHeightStretchJNI(mNativePointer);
}
public YogaValue getMaxWidth() {
return valueFromLong(YogaNative.jni_YGNodeStyleGetMaxWidthJNI(mNativePointer));
}
@@ -493,6 +553,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetMaxWidthPercentJNI(mNativePointer, percent);
}
public void setMaxWidthMaxContent() {
YogaNative.jni_YGNodeStyleSetMaxWidthMaxContentJNI(mNativePointer);
}
public void setMaxWidthFitContent() {
YogaNative.jni_YGNodeStyleSetMaxWidthFitContentJNI(mNativePointer);
}
public void setMaxWidthStretch() {
YogaNative.jni_YGNodeStyleSetMaxWidthStretchJNI(mNativePointer);
}
public YogaValue getMaxHeight() {
return valueFromLong(YogaNative.jni_YGNodeStyleGetMaxHeightJNI(mNativePointer));
}
@@ -505,6 +577,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetMaxHeightPercentJNI(mNativePointer, percent);
}
public void setMaxHeightMaxContent() {
YogaNative.jni_YGNodeStyleSetMaxHeightMaxContentJNI(mNativePointer);
}
public void setMaxHeightFitContent() {
YogaNative.jni_YGNodeStyleSetMaxHeightFitContentJNI(mNativePointer);
}
public void setMaxHeightStretch() {
YogaNative.jni_YGNodeStyleSetMaxHeightStretchJNI(mNativePointer);
}
public float getAspectRatio() {
return YogaNative.jni_YGNodeStyleGetAspectRatioJNI(mNativePointer);
}

Some files were not shown because too many files have changed in this diff Show More