Summary:
This diff changes updateState method to support null stateWrappers, before this method would crash with a NullPointerException, now it allows the null object to reach the view manager.
Changelog: Add support for update of nullable localState in Fabric
Reviewed By: JoshuaGross
Differential Revision: D17939651
fbshipit-source-id: c62555905e39f9e0db75b9e1d1b93f33d0560266
Summary:
The Android makefiles had hard-coded paths to hermes-engine, sometimes looking in `node_modules` and other times looking in `..`. This commit implements the Node module resolution algorithm (see common.mk), which handles both of these cases and also looks further up the root if necessary, handling the case when the `hermes-engine` npm package is hoisted.
This commit does three things:
- Defines `find-node-module` and uses it in the makefiles to find `hermes-engine`
- Removes the unused `/path/to/hermes-engine/include` paths since this directory does not exist and should be `/path/to/hermes-engine/android/include` (`android`)
- Moves the definition of `REACT_NATIVE` in the makefiles to the top. It was defined after every `$(CLEAR_VARS)` invocation but was not actually cleared anyway. `$(CLEAR_VARS)` resets only `LOCAL_*` variables in this list: https://android.googlesource.com/platform/build/+/7dc45a8/core/clear_vars.mk
## Changelog
[Internal] [Changed] - Android Makefiles look for hermes-engine using Node's module resolution algorithm
Pull Request resolved: https://github.com/facebook/react-native/pull/26820
Test Plan: Run `./gradlew :ReactAndroid:installArchives`, which requires the hermes-engine paths to be correct in order to find the headers.
Differential Revision: D17923671
Pulled By: cpojer
fbshipit-source-id: 9238b8718a94080db1abbba6375a6a1d484c871d
Summary:
Currently the react native framework doesn't handle the accessibility state changes of the focused item that happen not upon double tapping. Screen reader doesn't get notified when the state of the focused item changes in the background.
To fix this problem, post a layout change notification for every state changes on iOS.
On Android, send a click event whenever state "checked", "selected" or "disabled" changes. In the case that such states changes upon user's clicking, the duplicated click event will be skipped by Talkback.
## Changelog:
[General][Fixed] - Announce accessibility state changes happening in the background
Pull Request resolved: https://github.com/facebook/react-native/pull/26624
Test Plan: Add a nested checkbox example which state changes after a delay in the AccessibilityExample.
Differential Revision: D17903205
Pulled By: cpojer
fbshipit-source-id: 9245ee0b79936cf11b408b52d45c59ba3415b9f9
Summary: Tear down FabricUIManager more aggressively. The rest of the ivars here we can't set to null (yet) because they're marked as final.
Reviewed By: mdvacca
Differential Revision: D17878342
fbshipit-source-id: a1c8ace2603750ac39c3d97e1aca6c486ba5fb79
Summary: UseVanillaJNI flag was missing for measure and baseline functions
Reviewed By: amir-shalem
Differential Revision: D17868201
fbshipit-source-id: 95d6843d643e90157a51550d6efbf059f0ca2c39
Summary: These methods are (or should be) only called on the UI thread. Make those assumptions explicit.
Reviewed By: mdvacca
Differential Revision: D17865205
fbshipit-source-id: 9b3acf8f3215a07b1a667ced55e50e99a488de79
Summary: Although `mBinding` is unregistered which means the connection to the JNI-bridged Cxx object can be destructed, we still hold onto the `mBinding` Java object after unregistering. That doesn't seem desirable, I think we should just clear it out here for consistency.
Reviewed By: mdvacca
Differential Revision: D17865206
fbshipit-source-id: 1ad8643c48ba0b2d52620a7b8ebe8a52928648ef
Summary:
Add UI thread assertions and annotations to ReactRootView. Shouldn't have any immediate effect since these methods already call other methods that assert they're on the UI thread. Doing this to hoist assumptions higher up.
Doing some very simple refactoring to the way cleanup happens to ensure aggressive cleanup in more instances.
Reviewed By: shergin
Differential Revision: D17860291
fbshipit-source-id: c87e0336594fa2327271b648eb8340e250235250
Summary: set missing useVanillaJNI, it was causing part of the unit-tests to run in fbjni instead of vanillajni.
Reviewed By: SidharthGuglani
Differential Revision: D17852635
fbshipit-source-id: 5bc187d90fbdc430015be55a015a7d1e0ba0ebc6
Summary: This PR caused a regression with shadows, see https://github.com/facebook/react-native/issues/26544.
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D17809320
fbshipit-source-id: 0c83cd211425622ada0fd8c492f43df0536a4b8a
Summary: Use TestParametrization to test both fbjni and vanilla jni versions
Reviewed By: amir-shalem
Differential Revision: D17788718
fbshipit-source-id: 0f3317b7403cadca7b7ccd9140f1933d746bf433
Summary: This diff moves methods related to actions on YGNode like free node, reset node etc. to vanilla JNI
Reviewed By: amir-shalem
Differential Revision: D17668008
fbshipit-source-id: 03bfc51ec1fcf06569713400f984d551827e22fe
Summary:
This PR addresses issue https://github.com/facebook/react-native/issues/23870 (`View.getGlobalVisibleRect()` is broken in some use cases)
The issue affects the following Android APIs:
- ViewGroup.getChildVisibleRect()
- View.getGlobalVisibleRect() (Which calls into ViewGroup.getChildVisibleRect)
- View.getLocalVisibleRect() (Which calls into View.getGlobalVisibleRect())
According to Android documentation, View.getGlobalVisibleRect() should provide a rect for a given view that has been clipped by the bounds of all of its parent views up the view hierarchy. It does so through the use of the recursive function ViewGroup.getChildVisibleRect().
Since React Native has a separate clipping mechanism that does not rely on Android UI's clipping implementation, ViewGroup.getChildVisibleRect() is unable to determine that a rect should be clipped if the clipping view is a ReactClippingViewGroup. This resultantly breaks some important use cases for things like testing with Detox, which relies on this functionality to tell when a component is on-screen, as explained in the above referenced issue.
The rationale of the fix is essentially to implement logic analogous to [ViewGroup.getChildVisibleRect()](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewGroup.java#6176), discarding irrelevant Android clipping modes, and instead testing against the 'overflow' property, restoring the originally intended functionality. This is implemented as an override to ViewGroup.getChildVisibleRect() in the following classes:
- ReactViewGroup
- ReactScrollView
- ReactHorizontalScrollView
Unfortunately, since the public ViewGroup.getChildVisibleRect() API recurses into a `hide` annotated API which cannot be overridden, it was necessary to provide this override in each of the above React Native classes to ensure the superclass implementation would not be called, which would break the recursion.
## Changelog
[Android] [Fixed] - View.getGlobalVisibleRect() clips result rect properly when overflow is 'hidden'
Pull Request resolved: https://github.com/facebook/react-native/pull/26334
Test Plan:
The functionality in question is neither used internally nor exposed by React Native, and thus only affects Android native modules that use the above referenced APIs.
As such, I have primarily performed testing with a forked example project that had been submitted with issue https://github.com/facebook/react-native/issues/23870, originally by d4vidi.
The example project can be found here:
- [Configured to build against RN Master](https://github.com/davidbiedenbach/RNClipVisibilityBugDemo/tree/rn-master)
- [Configured to build against PR branch](https://github.com/davidbiedenbach/RNClipVisibilityBugDemo/tree/fix-23870)
(Original project here: https://github.com/d4vidi/RNClipVisibilityBugDemo)
### Bug in effect:
When built against RN master, it can be observed that fully clipped views are reported as visible, as in the below screenshots.
#### Views inside a ReactViewGroup do not report as clipped

#### Views inside a ReactScrollView do not report as clipped

#### Views inside a ReactHorizontalScrollView do not report clipping properly

### Bug fixed
When built against the PR branch, fully-clipped views no longer report visible.
#### Views inside a ReactViewGroup report clipping properly

#### Views inside a ReactScrollView report clipping properly

#### Views inside a ReactHorizontalScrollView report clipping properly

Reviewed By: mdvacca
Differential Revision: D17782658
Pulled By: yungsters
fbshipit-source-id: 0cd0d385898579a7a8a3e453f6ba681679ebe496
Summary: Oleksandr made the point that making `sDidInit` volatile isn't quite enough because the flag is set at the beginning of the function; it's possible that it will return true while it's still in the process of initializing the bridge. Moving where we set the flag to the end of the function should address the issue.
Reviewed By: JoshuaGross
Differential Revision: D17770128
fbshipit-source-id: 695d3edc582d9dce1884d8698d400dd147ca5cae
Summary: Fabric doesn't support setNativeProps, so we have to use commands instead to set the value of the native component.
Reviewed By: JoshuaGross
Differential Revision: D17736274
fbshipit-source-id: 18c47365926c3c2cfc3551f4b5b6cc72e4162367
Summary: Adding a second exception with a different error message so we can tell how the ViewManagerRegistry was created when it fails to find a view manager.
Reviewed By: rickhanlonii, JoshuaGross
Differential Revision: D17759060
fbshipit-source-id: 4415fa7440395f7e5730d2b77088f16a1a6a819d
Summary: In D17747958 I added a function to check the value of a static variable, but forgot to make sure it was accessed in a thread-safe manner. Adding `volatile` to the flag
Reviewed By: makovkastar
Differential Revision: D17763888
fbshipit-source-id: f227b69de1a0df6493424da3b276529555999f70
Summary: Adding a hook to check if ReactBridge is initialized so we can avoid loading the .so on the main thread.
Reviewed By: fkgozali
Differential Revision: D17747958
fbshipit-source-id: 5969afa57dc1b446c03bc68eaa9e1385fe17c461
Summary:
Currently, horizontal `ScrollViews` don't properly support `removeClippedSubviews`.
This is because the container view, `ReactHorizontalScrollContainerView` extends from regular `ViewGroup` instead of `ReactViewGroup` so doesn't have all the logic around clipping children.
Moreover, the `ReactHorizontalScrollContainerViewManager` doesn't actually support the `removeClippedSubviews` prop
This change:
- Makes `ReactHorizontalScrollContainerView` extend from `ReactViewGroup` while maintaining the special logic around RTL scrolling
- Factors out a common `ReactClippingViewManager` which will be used to bridge all components which extend `ReactViewGroup` and support clipping. It has the logic for adding/removing children and getting child counts while considering clipped subviews
- `ReactViewManager` now extends this new `ReactClippingViewManager`
- `ReactHorizontalScrollContainerViewManager` also extends `ReactClippingViewManager`
Reviewed By: JoshuaGross
Differential Revision: D17708630
fbshipit-source-id: d257566ee54ad46f6d62f176a657c596bba96aa4
Summary:
Fabric expects the measure method to return the size in density-independent pixels, but getMeasuredWidth and getMeasuredHeight return pixels on Android, so we have to convert these values before returning to C++.
Check the method createUpdateLayoutMountItem in Binding.cpp:
```
local_ref<JMountItem::javaobject> createUpdateLayoutMountItem(
const jni::global_ref<jobject> &javaUIManager,
const ShadowViewMutation &mutation) {
...
int x = round(frame.origin.x * pointScaleFactor);
int y = round(frame.origin.y * pointScaleFactor);
int w = round(frame.size.width * pointScaleFactor);
int h = round(frame.size.height * pointScaleFactor);
auto layoutDirection = toInt(newChildShadowView.layoutMetrics.layoutDirection);
return updateLayoutInstruction(
javaUIManager, newChildShadowView.tag, x, y, w, h, layoutDirection);
}
return nullptr;
}
```
We are interested in the next two lines:
```
int w = round(frame.size.width * pointScaleFactor);
int h = round(frame.size.height * pointScaleFactor);
```
`frame.size.width` and `frame.size.height` are the values returned from the measure method in Java and they are multiplied by the screen density to get the size in pixels, which means Fabric expects these values to be DIPs.
Reviewed By: shergin
Differential Revision: D17626834
fbshipit-source-id: f9856b5d0796c75c26c84adf11e1652b22a1ddef
Summary:
We use `ViewManager.onMeasure` to perform measurements of Android views and pass the measured size back to Yoga. For Android in order to the report correct dimensions of a View, this View must be created using a Context that has a theme associated with it. Before, `onMeasure` only had ReactApplicationContext passed as the first parameter and ReactSwitch, for example, could not be measured correctly (because it uses the size of the thumb drawable, which is extracted from the current theme). This diff adds surfaceId as the first parameter of `FabricUIManager.measure`, so that we can retrieve ThemedReactContext and pass it to `ViewManager.onMeasure`.
The size of the Switch component is still incorrect, but at least the size reported back to Yoga is the same as in Paper. So there is more investigation necessary why this happens in Fabric. I will investigate and publish another diff with the fix.
Reviewed By: JoshuaGross, shergin
Differential Revision: D17625959
fbshipit-source-id: 48197a61240fb13042bef3e9f5d681acacc702fb
Summary:
In this diff we integrate the Switch component on Android in Fabric. Since the component has a custom measure function, we need to write some C++ to call the measure method in Java.
The component isn't fully functional yet (setNativeProps isn't supported in Fabric) and has some problems with measuring itself. I will fix the component in the next diffs in this stack.
Reviewed By: JoshuaGross
Differential Revision: D17571258
fbshipit-source-id: be4e201495b9b197ddec44ee3484357bfb6225a8
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/26623
I noticed the min version was 10. It is actually 9 if we consider users with developer option turned on.
Changelog:
[Android][Fixed] - Updated Appearance module to allow Android 9/P devices.
Differential Revision: D17632656
fbshipit-source-id: 893699ae37ab1cef64fe2547e0f2d6858bf3c48c
Summary: This diff fixes the issue with view paddings in Fabric introduced in D17081799. In Paper setting padding on a view was only supported for Text and TextInput components (see https://fburl.com/codesearch/6r6lu5vd). We want to keep Fabric backwards compatible, so we delegate setting the padding to the view manager instead of setting it directly on the view. In this way we can have a no-op implementation in the base view manager and implement this method only in view managers that support setting padding (ReactTextInputManager and ReactTextViewManager at the moment).
Reviewed By: JoshuaGross
Differential Revision: D17665011
fbshipit-source-id: 38bc56278e002bd34881cfcb9ed79df579f79e28
Summary:
Because of the changes made in Fabric, the order of the execution of some methods in ViewManager has changed. In Paper the following order was guaranteed: `createViewInstance -> addEventEmitters -> updateProperties -> onAfterUpdateTransaction`. But in Fabric, the order is the following: `createViewInstance -> updateProperties -> onAfterUpdateTransaction -> addEventEmitters`. This change can actually break some existing view managers, because they rely on the fact that `addEventEmitters` will be called before `onAfterUpdateTransaction`. Check ReactVideoManager:
```
ReactModule(name = ReactVideoManager.REACT_CLASS)
public class ReactVideoManager extends SimpleViewManager<ReactVideoPlayer>
implements VideoManagerInterface<ReactVideoPlayer> {
...
Override
protected void onAfterUpdateTransaction(ReactVideoPlayer view) {
super.onAfterUpdateTransaction(view);
view.commitChanges();
}
Override
protected void addEventEmitters(
final ThemedReactContext reactContext, final ReactVideoPlayer view) {
view.setStateChangedListener(
new ReactVideoPlayer.PlayerStateChangedListener() {
...
}
```
As you can see there is a state change listener registered in `addEventEmitters` and `view.commitChanges()` can actually cause a state change. It means that if `onAfterUpdateTransaction` is executed before `addEventEmitters`, the state change listener will be added after a state change has happened and the event will be missed.
Reviewed By: JoshuaGross
Differential Revision: D17600308
fbshipit-source-id: 044e09e0d64973c8237876311d37c057a1ba384e
Summary: This diff makes the Video component compatible with Fabric on Android.
Reviewed By: JoshuaGross
Differential Revision: D17450815
fbshipit-source-id: 5e47d8cdca96f9fbe72902bac7dd157f7b5fdb1a
Summary: Converting the SourceCode native module to TurboModules. Checking in the Java class generated from the JS spec and extending it in the module implementation.
Reviewed By: fkgozali
Differential Revision: D17586276
fbshipit-source-id: 3d2080f1280791e81a0366d0aab101d960d11157
Summary: This diff adds a method to call whenever a fast refresh happens. Right now this is only useful for reporting.
Reviewed By: cpojer
Differential Revision: D17528033
fbshipit-source-id: 17e82abe7a3e2bab6829de5adecda853fe5335c5
Summary:
This diff adds reloadWithReason to the NativeDevSettings and updates the exposed DevSettings.reload method to send to it if it's available (setting an 'uncategorized' reason if one isn't set.
[General][Feature] Update DevSettings.reload to accept a reason
Reviewed By: RSNara
Differential Revision: D17499343
fbshipit-source-id: e8c9724800f93d3b9a5d2a8fe9f689d51947d39b
Summary: This diff fixes the height of the Slider component in Fabric on Android. Note that the layout is still broken (no padding and the seek bar is misaligned, but it's another issue).
Reviewed By: JoshuaGross
Differential Revision: D17629798
fbshipit-source-id: af8cae909279dc92ee1c80b9be2f5c578972eafc
Summary:
When sliders are adjusted via accessibility, no onSlidingComplete callback is
generated. This causes problems for components which perform behavior in this
callback, and means that such components don't behave properly when adjusted via
accessibility. For example, if an app hosting a volume control slider only commits the volume change to the hardware on onSlidingComplete, it is impossible for a screen reader user to ever actually adjust the volume.
Ensure that sliders call the onSlidingComplete callback after adjusted via
accessibility.
## Changelog
[General] [Fix] - Add onSlidingComplete callbacks when sliders adjusted via a11y.
[CATEGORY] [TYPE] - Message
Pull Request resolved: https://github.com/facebook/react-native/pull/26600
Test Plan: Prior to this change, using the RNTester slider example with a screen reader, the onSlidingComplete callback tests never shows any callbacks when the slider is adjusted. With this change applied, the callback test will show a number of callbacks corresponding to the number of times the slider was adjusted via the screen reader.
Differential Revision: D17661157
Pulled By: cpojer
fbshipit-source-id: a6eedef099c6c1b571b290c329059ac9b69b53dd
Summary:
## Motivation
I have seen a spike in users reporting this error. Unfortunately I did not receive any repros that would confirm this, but my hypothesis is that they ran into situation when `new XYZPackage()` was present in `getPackages()` method and then the CLI kicked in with autolinking and they were left with this incomplete error.
someone more knowledgeable of autolinking should review this.
Pull Request resolved: https://github.com/facebook/react-native/pull/26467
Differential Revision: D17661242
Pulled By: cpojer
fbshipit-source-id: 63dfcd85a0d41d85a0dd52f84ab16cb7ceb64ba2