Summary:
This PR prevents blob data from being prematurely de-allocated in native code when using slice to create views into an existing blob. Currently, whenever a new blob is created via createFromOptions, BlobManager.js creates a new blobCollector object since options.__collector is never provided.
https://github.com/facebook/react-native/blob/dc80b2dcb52fadec6a573a9dd1824393f8c29fdc/Libraries/Blob/BlobManager.js#L115-L123
When the reference to a blobCollector is garbage collected, the corresponding native memory for the blob data is de-allocated.
https://github.com/facebook/react-native/blob/27651720b40cab564a0cbd41be56a02584e0c73a/Libraries/Blob/RCTBlobCollector.mm#L19-L25
Since, `blob.slice()` is supposed to create a new view onto the same binary data as the original blob, we need to re-use the same collector object when slicing so that it is not GC'd until the last reference to the binary data is no longer reachable. Currently, since each blob slice gets a new blobCollector object, the memory is de-allocated when the first blob is GC'd.
Fixes https://github.com/facebook/react-native/issues/29970
Fixes https://github.com/facebook/react-native/issues/27857
## Changelog
<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->
[iOS] [Fixed] - Blob data is no longer prematurely deallocated when using blob.slice
Pull Request resolved: https://github.com/facebook/react-native/pull/31392
Test Plan: I could use help coming up with a test plan here. I could add a referential equality check for the blob.data.__collector in `Blob-test` but it doesn't seem quite right to be testing the implementation detail there.
Reviewed By: javache
Differential Revision: D41730782
Pulled By: cortinico
fbshipit-source-id: 5671ae2c69908f4c9acb5d203ba198b41b421294
Summary:
```js
async () => {
let blobs = [];
for (let i = 0; i < 4; i++) {
const res = await fetch();
blobs = [...blobs, await res.blob()]
}
const blob = new Blob(blobs); // <<<<<<<<<<<<<<< a
return await new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = async () => {
await RNFS.writeFile(destPath, (fileReader.result as string).split(',')[1], 'base64');
resolve(destPath);
};
fileReader.onabort = () => {
reject('');
};
fileReader.onerror = (event) => {
reject('');
};
fileReader.readAsDataURL(blob); // <<<<<<<<<<<<<<< b
});
}
```
Sometime `fileReader.readAsDataURL` is unable to get blob from the dictionary after `new Blob(blobs)` and then reject with `Unable to resolve data for blob: blobId` in iOS or `The specified blob is invalid` in android. Because line `a` and `b` can be run in different thread. `new Blob([])` is in progress and `fileReader.readAsDataURL` accesses the blob dictionary ahead of the blob creation.
The expected behaviour is it should finish new Blob([]) first and then readAsDataURL(blob)
To fix that, there should be a lock inside the method `createFromParts`. For iOS, It needs to be a recursive_mutex to allow same thread to acquire lock
## Changelog
<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->
[iOS] [Fixed] - fix the race condition when calling readAsDataURL after new Blob(blobs)
Pull Request resolved: https://github.com/facebook/react-native/pull/34096
Reviewed By: cipolleschi
Differential Revision: D37514981
Pulled By: javache
fbshipit-source-id: 4bf84ece99871276ecaa5aa1849b9145ff44dbf4
Summary:
We are currently seeing warning `Native Component 'X' that calls codegenNativeComponent was not code generated at build time. Please check its definition.` even though we have not opted into Fabric. This warning is not actionable and is just noisy.
See also discussion: https://github.com/reactwg/react-native-releases/discussions/21#discussioncomment-2657180
## Changelog
[General] [Fixed] - Remove unactionable warning about `codegenNativeComponent` when on 'Paper'
Pull Request resolved: https://github.com/facebook/react-native/pull/33830
Test Plan: n/a
Reviewed By: dmitryrykun
Differential Revision: D36377844
Pulled By: cortinico
fbshipit-source-id: 23c9f9dbf0ce1cea60c5dc8caa02d0dc53bd635d
Summary:
When a FlatList is nested inside another FlatList, it may be re-rendered whenever the outer FlatList renders. Apply the same optimization we already had in `VirtualizedListContextProvider` to avoid changing the context object if no values have changed.
Changelog: [General][Changed] - Optimized VirtualizedList context when used with nested lists
Reviewed By: genkikondo
Differential Revision: D35905952
fbshipit-source-id: 695253c85db2043d22e208ad94ecc7daa1455055
Summary:
Apple suggested to this new API on iOS 10+.
> // Any new bitmap drawing code is encouraged to use UIGraphicsImageRenderer in lieu of this API.
WWDC18 Reference: https://developer.apple.com/videos/play/wwdc2018/219/
> Use UIGraphicsImageRenderer to create and draw to an image buffer
Supports Wide Color, unlike UIGraphicsBeginImageContext()
Combine with UIImageView for efficient offscreen rendering
Per https://nshipster.com/image-resizing/#performance-benchmarks, the new API runs even faster than the C version, probably due to more smart context reuses/management.
Changelog:
[iOS][Changed] - Adopt UIGraphicsImageRenderer API
Reviewed By: philIip
Differential Revision: D35699584
fbshipit-source-id: 7a1e2109d5e121fb396c1014f4ed0a892211b0cc
Summary:
Fixes https://github.com/facebook/react-native/issues/33529 (note that I reproduced the bug on iOS too).
The bug comes from the fact that we were using `this._scrollMetrics.offset` to determine if the initial scroll was done. But sometimes it equals 0 even after the initial scroll is done, for example when the content does not fill the list. So I replaced it with `this._hasDoneInitialScroll`.
I believe that `this._hasDoneInitialScroll` was not used in the first place because it was introduced later (3 years ago vs 5 years ago for the original code).
The replacement correctly fixes the broken test case and the example given in the issue.
Then I had to update two test cases (rename the first and remove the second), that shows explicitly the broken behavior:
we have to simulate the initial scroll for the content to be adjusted, so when the content does not fill the view and the scroll cannot be executed, the content is not adjusted.
## Changelog
[General] [Fix] - Fix VirtualizedList with initialScrollIndex not rendering all elements when data is updated
Pull Request resolved: https://github.com/facebook/react-native/pull/33558
Test Plan:
- I added a broken test case based on the issue
- I tested with the RNTesterApp using the code example given in the issue
Reviewed By: ryancat
Differential Revision: D35503114
Pulled By: yungsters
fbshipit-source-id: 67bb75d7cf1ebac0d59127d0d45afbaa3167dcf3
Summary:
Changelog: [Internal][SVC][JS] Refactor the JS base SVC StaticViewConfig to be easier to understand
This diff is a refactor that doesn't change any logic.
# Context
NativeViewConfigs are generated from RCTViewManager in iOS and ViewManager in Android.
StaticViewConfigs are partially generated from JS, and partially handwritten in JS.
We've noticed in at least 2 instances that engineers who add new props to NativeViewConfigs sometimes don't put props in the correct place for StaticViewConfigs, and thus they accidentally break the landblocking jest e2e test that validates the StaticViewConfigs matches the NativeViewConfigs.
The human error is mostly because PlatformBaseViewConfig.js was too nested to be easily understood. This diff refactors PlatformBaseViewConfig.js and adds clarifying comments.
Reviewed By: RSNara
Differential Revision: D35623775
fbshipit-source-id: 498a3daa812fa314821a2e7cb7d6f809900dbe3a
Summary:
Changelog: [Internal][Fixed] Fix StaticViewConfigs for Android, by removing iOS-only accessibilityLanguage prop
The accessibilityLanguage was a prop added to RCTViewManager, that is iOS-only, so it shouldn't exist in the SVCs for Android.
Reviewed By: RSNara
Differential Revision: D35630945
fbshipit-source-id: 7ed7f2619f73bb88babfbb207793d5415addaee6
Summary:
This drastically improves `Animated.interpolate` performance when `inputRange` has a considerable amount of elements (~100 in my tests).
For instance in `ActivityIndicator` inside `react-native-paper`, the input has 144 elements https://github.com/callstack/react-native-paper/blob/main/src/components/ActivityIndicator.tsx#L170. `react-native-elements` has 9k stars, so I'm assuming this is widely used.
### Cause
The reason for the performance drop is that if we assume `n` to be the size of the range, calculating `'inputRange must be monotonically non-decreasing ' + arr` essentially calculates `arr.toString()` which has O(n) complexity.
Since it is recalculated in a for loop, we end up with `checkValidInputRange` having a O(n²) complexity. Which means ~10k operations if the array has a size close to 100.
## Changelog
[General] [Fixed] - Fix performance issue on Animated.interpolate with big input range
Pull Request resolved: https://github.com/facebook/react-native/pull/33598
Test Plan:
[Here's a repo](https://github.com/Almouro/AnimatedInterpolationRepro) reproducing the issue.
The branch `fix` includes the fix.
Clicking `Interpolate` runs:
```js
new Animated.Value(0).interpolate({
inputRange: Array(144)
.fill()
.map((_, i) => 1 / (i + 1))
.reverse(),
outputRange: Array(144)
.fill()
.map((_, i) => 1 / (i + 1))
```
Here's a comparison of JS thread perf before the fix and after the fix:
- on a Samsung J3 2017 (lower end)
- using Flipper and https://github.com/bamlab/react-native-performance)
- ` __DEV__` mode deactivated
- clicking the button and waiting 15s
| Before | After |
|----------|:-------------:|
|  | |
The error still throws if `inputRange` is incorrect:
<img width="517" alt="image" src="https://user-images.githubusercontent.com/4534323/162439219-6ce120ae-98e5-496b-899a-492978689d6d.png">
However if `__DEV__` mode is deactivated, no error is thrown
Reviewed By: yungsters
Differential Revision: D35507441
Pulled By: javache
fbshipit-source-id: 36ac49422f7a42d247130c42d12248b2be1232c6
Summary:
Allow modifying iOS image cache limits. Currently the image cache imposes some strict limits:
[NSCache.totalCostLimit](https://developer.apple.com/documentation/foundation/nscache/1407672-totalcostlimit?language=objc) of 20MB.
Single Image Size Limit of 2MB (bitmap size).
This may not be enough for applications that make heavy use of images. With this commit it is possible to fine tune them to the applications need.
This can be set for example in the App Delegate with:
```objc
RCTSetImageCacheLimits(4*1024*1024, 200*1024*1024);
```
This would increase the single image size limit to 4 MB and the total cost limit to 200 MB.
## Changelog
[iOS] [Added] - Allow modifying iOS image cache limits
Pull Request resolved: https://github.com/facebook/react-native/pull/33554
Test Plan: There is no easy way to test this except adding the above snippet and checking via break points that the new limits are used.
Reviewed By: cipolleschi
Differential Revision: D35485914
Pulled By: cortinico
fbshipit-source-id: 646cf7cab5ea5258d0d0d0bce6383317e27e4445
Summary:
Changelog:
[iOS][Changed] - Update `PushNotificationIOS.checkPermissions` to include iOS 10+ notification settings.
`PushNotificationIOS.checkPermissions` is currently limited to only return:
* alert :boolean
* badge :boolean
* sound :boolean
That's has been a number of new properties since iOS 10 that we should support to improve pushability signal. This diff updates the logic to support 4 new available settings:
* critical :boolean,
* lockScreen :boolean,
* notificationCenter :boolean,
* autorizationStatus: number,
Reviewed By: philIip
Differential Revision: D35386762
fbshipit-source-id: 07c87de024756bc95a2c822ac35437ec76b3c903