Summary:
In D17439957, I noted that YogaLogger#log throws a NoMethodFoundException when called from C++ b/c C++ and Java's signatures of that method don't match. C++ uses YogaNodeJNIBase for the first param, Java uses YogaNode. Both my attempts to fix this failed.
Attempt #1 - Make Java use YogaNodeJNIBase. This doesn't work because the :java-interface target includes YogaLogger but not YogaNodeJNIBase. Moving YogaLogger to the impl target doesn't work either b/c other files in :java-interface reference YogaLogger.
Attempt #2 - Make C++ use YogaNode. This doesn't work b/c we try to call the log method with objects of fbjni type YogaNodeJNIBase. This would be fine in Java since YogaNodeJNIBase extends YogaNode. But fbjni's typing isn't advanced enough to know this, so the Yoga C++ fails to compile.
At this point, I was wondering what the value of having this param in the log function at all was. None of the implementations in our codebase use it today. It might be easier to just remove it all together. This also removes a bug with YGNodePrint where we pass a null layout context that eventually causes a SIG_ABRT when we use it to try to find a YogaNode to pass to this function. (https://fburl.com/diffusion/ssw9h8lv).
Reviewed By: amir-shalem
Differential Revision: D17470379
fbshipit-source-id: 8fc2d95505971a52af2399a9fbb60b63f27f0ec2
Summary: Adding `DoNotStrip` to all the interfaces that extend `JavaScriptModule` to ensure they don't get stripped from release builds (because they have no Java implementors).
Reviewed By: emma0303
Differential Revision: D17534719
fbshipit-source-id: a793764caf17040bf1252be7ec4c72176d6989d4
Summary: Another attempt at D17282188, which got partially reverted in D17505827 due to a crash in release builds.
Reviewed By: RSNara
Differential Revision: D17512419
fbshipit-source-id: a1b0abfed2c4a1f3f02da85e84abee0127b1a7e2
Summary:
When using a medium (500) font weight on Android the wrong weight is used for the placeholder and for the first few seconds of input (before it gets text back from JS). To fix it I refactored the way we handle text styles (family, weight, style) to create a typeface to be more like the `Text` component.
Since all these 3 props are linked and used to create the typeface object it makes more sense to do it at the end of setting props instead of in each prop handler and trying to recreate the object without losing styles set by other prop handlers. Do do that we now store fontFamily, fontStyle and fontWeight as ivar of the ReactEditText class. At the end of updating prop if any of those changed we recreate the typeface object.
This doesn't actually fix the bug but was a first step towards it. There were a bunch of TODOs in the code to remove duplication between `Text` and `TextInput` for parsing and creating the typeface object. To do that I simply moved the code to util functions in a static class. Once the duplication was removed the bug was fixed! I assume proper support for medium font weights was added for `Text` but not in the duplicated code for `TextInput`.
## Changelog
[Android] [Fixed] - Fix medium font weights for TextInput on Android
Pull Request resolved: https://github.com/facebook/react-native/pull/26434
Test Plan:
Tested in my app and in RNTester that custom styles for both text and textinput all seem to work.
Repro in RNTester:
```js
function Bug() {
const [value, setValue] = React.useState('');
return (
<TextInput
style={[
styles.singleLine,
{fontFamily: 'sans-serif', fontWeight: '500', fontSize: 32},
]}
placeholder="Sans-Serif 500"
value={value}
onChangeText={setValue}
/>
);
}
```
Before:
![font-bug-1](https://user-images.githubusercontent.com/2677334/64902280-6889fc00-d672-11e9-8f44-9e524d844a6c.gif)
After:
![font-bug-2](https://user-images.githubusercontent.com/2677334/64902282-6cb61980-d672-11e9-8163-ace0f23070b6.gif)
Reviewed By: mmmulani
Differential Revision: D17468825
Pulled By: JoshuaGross
fbshipit-source-id: bc2219facb94668551a06a68b0ee4690e5474d40
Summary: This diff migrates `ReactSwtichManager` to use the generated `ReactSwtichManagerDelegate` for setting its properties.
Reviewed By: TheSavior
Differential Revision: D17395067
fbshipit-source-id: 1489c5d08cef860030ecbd23ef19bd8de1328d71
Summary: This diff migrates `ReactDrawerLayoutManager` to use the generated `AndroidDrawerLayoutManagerDelegate` for setting its properties.
Reviewed By: mdvacca
Differential Revision: D17343383
fbshipit-source-id: 85cd7ee3531b152da2601048f5e458f5dad73ad6
Summary: This diff migrates `ReactProgressBarViewManager` to use the generated `AndroidProgressBarManagerDelegate` for setting its properties.
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D17315619
fbshipit-source-id: 6293c6fc18567a934b6f3dce9b77abcc408052d8
Summary: This diff migrates `SwipeRefreshLayoutManager` to use the generated `AndroidSwipeRefreshLayoutManagerDelegate`.
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D17225894
fbshipit-source-id: e659d2a9cb5dba42c589559f61a0e98330e21612
Summary: This diff migrates `ReactModalHostManager` to use the generated `ModalHostViewManagerDelegate` for setting its properties.
Reviewed By: mdvacca
Differential Revision: D17205817
fbshipit-source-id: 6724302fd4301f9df92df04fcfb41f0c2c939d9f
Summary: This diff migrates `ReactSliderManager` to use the generated `SliderManagerDelegate` for setting its properties.
Reviewed By: mdvacca
Differential Revision: D17203078
fbshipit-source-id: 726736ef275074ecb799b334342ac64976153e2b
Summary: Fix for crash introduced by D17282188; doesn't cleanly revert, so just reverting this part
Reviewed By: JoshuaGross, RSNara
Differential Revision: D17505827
fbshipit-source-id: 3232285c0f15dabeb819f8806ad35d4ec83a1e53
Summary:
Self explanatory.
1. **Existing:** We create the NativeModules thread in CatalystInstanceImpl.cpp.
2. D17422165: We wrap this thread in a `BridgeNativeCallInvoker`.
3. D17422164: We use `CatalystInstanceImpl::getNativeCallInvokerHolder()` to get a hold of the `BridgeNitiveCallInvoker` in Java.
4. D17422163: From Java, we pass this `CallInvokerHolder` to `TurboModuleManager`'s constructor.
5. **This diff:** `TurboModuleManager` then unwraps the `CallInvoker` from `CallInvokerHolder`, and passes it to all TurboModules in their constructor.
Reviewed By: PeteTheHeat
Differential Revision: D17422160
fbshipit-source-id: c0a76dfe5fdedac2e0e21f7a562bc7588dc190fb
Summary:
In the previous diffs, I:
1. D17422165: Created a `CallInvoker` for the NativeModules thread.
2. D17422164: Exposed this `CallInvoker` via `CatalystInstance.getNativeCallInvokerHolder()`.
In this diff, I:
1. Make TurboModuleManager accept the NativeModules thread `CallInvoker` as a constructor argument.
Reviewed By: PeteTheHeat
Differential Revision: D17422163
fbshipit-source-id: cbaac2fc06f7f726d89e0c545154123ad7410e62
Summary: CatalystInstanceImpl is responsible for creating the NativeModules thread. We therefore expose a method `getNativeCallInvokerHolder()` on this hybrid class to create and give us access to the `CallInvokerHolder` for the NativeModules thread.
Reviewed By: PeteTheHeat
Differential Revision: D17422164
fbshipit-source-id: 316423847518124115643549fa73a8533d493cd0
Summary:
## Motivation
The concept behind JSCallInvoker doesn't necessarily have to apply only to the JS thread. On Android, we need to re-use this abstraction to allow execution of async method calls on the NativeModules thread.
Reviewed By: PeteTheHeat
Differential Revision: D17377313
fbshipit-source-id: 3d9075cbfce0b908d800a366947cfd16a3013d1c
Summary:
This PR removes Java reflection use in ReactDrawerLayoutManager.java because we all use AndroidX and setDrawerElevation is available. Also adds NonNull annotations
## Changelog
[Android] [Changed] - cleanup DrawerLayoutAndroid
Pull Request resolved: https://github.com/facebook/react-native/pull/26497
Test Plan: RNTester is working as expected.
Differential Revision: D17488727
Pulled By: mdvacca
fbshipit-source-id: fd626e3e7aca3965f62c4c82a55c69e81facc61d
Summary:
This PR is extracts and reuses ANDROIDX_TEST_VERSION, and is part of Gradle script refactoring effort.
## Changelog
[Android] [Changed] - extract and reuse ANDROIDX_TEST_VERSION
Pull Request resolved: https://github.com/facebook/react-native/pull/26487
Differential Revision: D17488766
Pulled By: mdvacca
fbshipit-source-id: f1968ffc403074d78d792eb5cc773cc6366ad2d1
Summary:
This diff splits up the current `createTimer` method (which is used for setTimeout, setInterval, etc.) into two methods, `createTimer` and `createAndMaybeCallTimer`. The latter is what's used by the existing Timing native module, and it preserves the existing behavior of this function.
What's the difference? The current implementation of createTimer makes some assumptions about how it's called - namely, that it's called from JS asynchronously (using the bridge). Right now when you create a timer from JS, the JSTimers module passes in the timestamp for when the timer was created; in the native `createTimer`, we compare this timestamp to the current time, and if we find the timer has already expired, we immediately invoke the callback.
Presumably this is done because we don't know how much time has elapsed since when the timer was scheduled in JS, and we want to make sure that it's called as soon as possible. Of course, this also means that `setTimeout(0)` will be immediately invoked, too, without waiting for the next frame.
This all sounds fine, until we take a look at immediates. Immediates are currently implemented entirely in JS, and are called by the JS bridge; before returning control to native, we flush the immediates queue.
This means that the current behavior is: 1) `setImmediate()` is always invoked before `setTimeout(0)`; 2) `setTimeout(0)` is invoked as soon as possible, before the next frame.
However, this changes with bridgeless RN. With bridgeless RN, the native module methods are being replaced by C++ host functions, which are called synchronously. So if we keep the current logic in JavaTimerManager (where it checks if the timer has already expired), then `setTimeout(0)` will be invoked **before** immediates are called.
So the change that I'm making for bridgeless RN is to always wait until the next frame before calling timers. This preserves the order of immediates/timers, although it does mean that `setTimeout(0)` will no longer be called as soon as possible. Of the two options, this seems preferable.
Reviewed By: PeteTheHeat
Differential Revision: D17403144
fbshipit-source-id: 8230f6ebe56aa20bfcf2325177c7812bc8e9c2ec
Summary:
This change restores the possibility of injecting custom root views via ReactAcitivtyDelegate. It has been used by react-native-gesture-handler library in order to replace default root view with a one that'd route touch events to gesture-handler internal pipeline.
The regression happened in d0792d4b8a where new `ReactDelegate` was introduced to provide support for rendering react native views in both Android fragments and activities. As a part of that change the logic responsible for creating root view has been moved from `ReactActivityDelegate` to `ReactDelegate` rendering `ReactActivityDelegate.createRootView` unused – that is there is no code path that leads to this method being called. Instead `ReactDelegate.createRootView` method has been added which now plays the same role. The custom root view injection was relying on overwriting that method and hence the method is no longer referenced overwriting it has no effect. Following the logic migration out of `ReactActivityDelegate` into `ReactDelegate` we could potentially now start overwriting methods of `ReactDelegate`. However when working with Android's activities in React Native we can only provide an instance of `ReactActivityDelegate` and in my opinion it does not make too much sense to expose also a way to provide own instance of `ReactDelegate`.
The proposed fix was to route `ReactDelegate.createRootView` to call `ReactActivityDelegate.createRootView` and this way regaining control over root view creation to `ReactActivityDelgate`. The change of the behavior has been implemented by subclassing `ReactDelegate` directly from `ReactActivityDelegate` and hooking the aforementioned methods together. Thanks to this approach, the change has no effect on `ReactDelegate` being used directly from fragments or in other scenarios where it is not being instantiated from `ReactActivityDelegate`.
This fixes an issue reported in https://github.com/kmagiera/react-native-gesture-handler/issues/745 and discussed on 0.61 release thread: https://github.com/react-native-community/releases/issues/140#issuecomment-532235945
## Changelog
[Internal] [Fixed] - Allow for custom root view to be injected via ReactActivityDelegate
Pull Request resolved: https://github.com/facebook/react-native/pull/26495
Test Plan:
1. Run RNTester, take layout snapshot, see the react root view being on the top of view hierarchy.
2. Run gesture-handler Example app (or some other app that overwrites ReactActivityDelegate.createRootView method), on layout snapshot see custom root view being used.
Differential Revision: D17482966
Pulled By: mdvacca
fbshipit-source-id: 866f551b8b077bafe1eb9e34e5dccb1240fa935e
Summary:
The next step to making our existing timers logic usable outside of the context of the native module. This diff removes the bridge access through ReactContext in JavaTimerManager, and instead relies on a delegate that implements the JSTimers interface. I'm reusing the JSTimers interface for convenience even though it extends JavaScriptModule, which I don't plan on using for bridgeless RN.
Also changing from ReadableArray to ReadableNativeArray so that it can be directly accessed from C++.
Reviewed By: PeteTheHeat
Differential Revision: D17282188
fbshipit-source-id: 5c5e0b12a2250334e96885c220feb52146e57c83
Summary:
Decoupling the logic for managing timers from the native module interface in TimingModule. I'm doing this so we can more easily share this logic with bridgeless RN, which won't use a native module for timers but instead will define the bindings with JSI.
This diff just moves things around and doesn't change any of the behavior.
Reviewed By: PeteTheHeat
Differential Revision: D17282187
fbshipit-source-id: ef54254dd0c7e2f6e294e9ae5a7d4b010f98de2e
Summary: Most of our other native modules end in 'module', so let's update Timing to match.
Reviewed By: RSNara
Differential Revision: D17260848
fbshipit-source-id: 808b4d370a7036a247724fda5ab7210ac985476b
Summary: This diff fixes two issues with the JNI integration of YogaLogger#log. (1) The YogaLogger class descriptor was missing a semicolon. This causes a ClassNotFoundException whenever you try to call the log method from C++. (2) The C++ signature for the class was using YogaNodeJNIBase as an arg but the Java signature was using YogaNode. This causes a MethodNotFoundException whenever you try to call the method after fixing problem 1.
Reviewed By: astreet
Differential Revision: D17439957
fbshipit-source-id: be3c16512558050265565b3688fb09a7da31b9b2
Summary:
This is a easy change in ReactEventEmitter that refactors the TAG used by this class to log events.
This is a follow up of D17422611
Reviewed By: makovkastar
Differential Revision: D17437034
fbshipit-source-id: 9974a244b24b04315c6a328696954b7acf7efbfd
Summary:
Reland https://github.com/facebook/react-native/pull/24767
The commit had to be reverted because it caused a crash when using remote debugging in chrome. This is normal since jsi is not available in that environment. The crash was caused by `jsContext.get()` being 0, then being dereferenced later in c++. We can simply skip initializing the blob collector in this case.
This also includes the fix from https://github.com/facebook/react-native/issues/25720 to fix a crash when using hermes.
## Changelog
[Android] [Fixed] - Release underlying resources when JS instance is GC'ed on Android
Pull Request resolved: https://github.com/facebook/react-native/pull/26155
Test Plan:
Test using RN tester with jsc and hermes
Test remote debugging
Reviewed By: mdvacca, fred2028
Differential Revision: D17072644
Pulled By: makovkastar
fbshipit-source-id: 079d1d43501e854297fbbe586ba229920c892584
Summary:
React Native components need a mechanism to specify their value to assistive technologies. This PR adds the notion of accessibilityValueDescription-- a property which either contains a textual description of a component's value, or for range-based components, such as sliders and progress bars, it contains range information (minimum, current, and maximum).
On iOS, the range-based info if present is converted into a percentage and added to the accessibilityValue property of the UIView. If text is present as part of the accessibilityValueDescription, it is used instead of the range-based information.
On Android, any range-based information in accessibilityValueDescription is exposed in the AccessibilityNodeInfo's RangeInfo. Text which is part of accessibilityValueDescription is appended to the content description.
## Changelog
[GENERAL] [Change] - add accessibilityValuedescription property.
Pull Request resolved: https://github.com/facebook/react-native/pull/26169
Test Plan: Added two new accessibility examples to RNTester, one which uses text and another which uses range-based info in accessibilityValueDescription. Verified that they both behave correctly on both Android and iOS.
Differential Revision: D17444730
Pulled By: cpojer
fbshipit-source-id: 1fb3252a90f88f7cafe1cbf7db08c03f14cc2321
Summary:
ReactAndroid Gradle was failing mysteriously with error below, because it was trying to read values from **android** when it wasn't configured completely.
```java
extensionSupplier.get()!!.compileSdkVersion must not be null
```
or
```java
compileSdkVersion is not specified.
```
It is happening because **buildReactNdkLib** task was created and configured eagerly. So this PR changes some tasks to be configured lazily, and reads values from **android** when ready. Also remove ANDROID_NDK variable check because android gradle plugin doing it automatically.
## Changelog
[Android] [Changed] - lazily configure ReactAndroid gradle tasks
Pull Request resolved: https://github.com/facebook/react-native/pull/26314
Test Plan: ./gradlew ReactAndroid:tasks run without errors, while master throws exception.
Differential Revision: D17177945
Pulled By: cpojer
fbshipit-source-id: c7a165092157d2059f946da70b801d1a475d4b8c
Summary:
Remove YogaNode.create() from the abstract class after we made sure nothing uses it anymore
This is the final stage to make `YogaNode` a pure class without JNI references
Reviewed By: SidharthGuglani
Differential Revision: D17280571
fbshipit-source-id: bd0eb138f7a6a9de8988fc0a7b90badbf635dac5
Summary:
Split YogaConfig into the same way YogaNode is split today.
Into an abstract class defining the interface, and actual JNI implementation
Reviewed By: SidharthGuglani
Differential Revision: D17266404
fbshipit-source-id: 3d5d6aa65c55cfa61d47c662d140cdce6dcb0ea1
Summary:
The concept of `EventBeat::Owner` was introduced in D17128549, this diff implements some missing pieces of that.
After the change, AsyncEventEmitter will check the existence of the "owner" (which is EventDispatcher) which guarantees that the rest of the pipeline is still alive (the validity of Runtime is guaranteed by RuntimeExecutor separately).
The overall workflow is described in D17128549.
Reviewed By: JoshuaGross
Differential Revision: D17410738
fbshipit-source-id: a1ae8e09600546874cdc7c622b3d884b71c5b48d
Summary:
This diff forces ReactEventEmitter to use RCTEventEmitter as default event emitter class. This is necessary because of T54134149.
This is a temporary fix until we find the root cause of T54134149
Reviewed By: JoshuaGross
Differential Revision: D17422611
fbshipit-source-id: 159b216434c79466427b7b1a2b0f71f466b0f606
Summary:
Expose native pointer thru an interface function for YogaConfig (its package private to `com.facebook.yoga` namespace),
This way we can make later on YogaConfig a pure abstract class.
Plus, it makes sure external users don't modify the pointer
Reviewed By: SidharthGuglani
Differential Revision: D17266401
fbshipit-source-id: f39b488cea0b73bc3578bb3aa90ab00139bf9271
Summary:
I wanted to configure the RN dev menu without having to write native code. This is pretty useful in a greenfield app since it avoids having to write a custom native module for both platforms (and might enable the feature for expo too).
This ended up a bit more involved than planned since callbacks can only be called once. I needed to convert the `DevSettings` module to a `NativeEventEmitter` and use events when buttons are clicked. This means creating a JS wrapper for it. Currently it does not export all methods, they can be added in follow ups as needed.
## Changelog
[General] [Added] - Export the DevSettings module, add `addMenuItem` method
Pull Request resolved: https://github.com/facebook/react-native/pull/25848
Test Plan:
Tested in an app using the following code.
```js
if (__DEV__) {
DevSettings.addMenuItem('Show Dev Screen', () => {
dispatchNavigationAction(
NavigationActions.navigate({
routeName: 'dev',
}),
);
});
}
```
Added an example in RN tester
![devmenu](https://user-images.githubusercontent.com/2677334/62000297-71624680-b0a1-11e9-8403-bc95c4747f0c.gif)
Differential Revision: D17394916
Pulled By: cpojer
fbshipit-source-id: f9d2c548b09821c594189d1436a27b97cf5a5737
Summary: I think this array is copied when we call the function over the JNI, and that we need to free the local copy we make.
Reviewed By: mdvacca
Differential Revision: D17377077
fbshipit-source-id: 82fe4ec89e95335a329f4ce562441561dbe88693
Summary:
This diff refactors ReactEventEmitter to not use the method ReactContext.getJSModule()
Since the initialization of events is performed by UIManagerModule or FabricUIManager classes we don't need to use JSModules as part of this class
Reviewed By: ejanzer
Differential Revision: D17176948
fbshipit-source-id: 6915a74b486851fbeda24f779d97873df22fd79b
Summary: Today, View Managers are all initialized as soon as we start up the app. Making them lazy, so that we only intantiate them when they are really needed
Differential Revision: D17329940
fbshipit-source-id: 821bf121f04d58c7b871c7923fed81d8c735f8b4
Summary:
Add standalone factory classes which generate YogaNode + YogaConfig, later on it will allow us to separate the yoga interface and actual implementation buck targets (see D17266406)
We've done such breakage change previously in D14122974.
Reviewed By: SidharthGuglani
Differential Revision: D17258196
fbshipit-source-id: b12f1a0d23c3f82b14cee0731a1daf1c015ee32c
Summary:
Removed unused file YogaNodeJNIPhantomRefs.java as this was causing oss build failures because of an import.
````:yoga:compileDebugJavaWithJavac/home/travis/build/facebook/yoga/java/com/facebook/yoga/YogaNodeJNIPhantomRefs.java:9: error: package com.facebook.jni does not exist
import com.facebook.jni.DestructorThread;
^
/home/travis/build/facebook/yoga/java/com/facebook/yoga/YogaNodeJNIPhantomRefs.java:30: error: package DestructorThread does not exist
new DestructorThread.Destructor(node) {
^
2 errors
FAILED
Reviewed By: pasqualeanatriello
Differential Revision: D17257330
fbshipit-source-id: 98b0c5d5b7dcd94bee559b58194c13b07f47723d
Summary:
Collapse many Remove/Delete mount items into a single batched item.
Since a delete is always preceded by a remove mountitem, we can batch these into one instruction. Since deletes tend to come in large blocks, it might make sense to batch many into a single instruction.
Reviewed By: mdvacca
Differential Revision: D17254631
fbshipit-source-id: abfd54cdb0bbb9a4c0880ec8e8bbd681367aecd4
Summary: Retain reference to reactNativeConfig to allow feature checks within core. This also rearranges the members of Binding to make them private instead of public.
Reviewed By: mdvacca
Differential Revision: D17275344
fbshipit-source-id: 67ad00aeebd3534a45a6ea8a28e14b7fcd9eb2e5
Summary: We were using an alias_ref which is like a raw pointer (not managed/retained); as it turns out, everywhere (?) else we accept an alias_ref we convert it to a global_ref (see Binding.cpp, JMessageQueueThread). We've just gotten lucky to not have already hit use-after-free errors.
Reviewed By: mdvacca
Differential Revision: D17275200
fbshipit-source-id: 581a51da36e96c353ed1117e9e0f428e65d36d69