Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35967
In https://github.com/facebook/react-native/issues/35936 we observed that the presence of AbsoluteSizeSpan may lead to hangs when using the Grammarly keyboard on Samsung.
This mitigation makes it so that we do not emit this span in any case where it is sufficient to rely on already set EditText textSize. In simple cases, tested on two devices, it causes typing into the TextInput to no longer hang.
This does not fully resolve the issue for TextInputs which meaningfully use layout-effecting spans (or at least font size), such as non-uniform text size within the input. We instead just try to reduce to minimum AbsoluteSizeSpan possible.
Testing the first commit was able to resolve hangs in some simpler inputs tested, by me and cortinico.
Changelog:
[Android][Fixed] - Mitigation for Samsung TextInput Hangs
Reviewed By: cortinico
Differential Revision: D42721684
fbshipit-source-id: e0388dfb4617f0217bc1d0b71752c733e10261dd
Summary:
`JNIEnv`'s `FindClass(..)` function takes the classes in the standard
`foo/bar/Baz` class specification (unless they're special, like arrays).
Specifying them with `Lfoo/bar/Baz;` results in a
`ClassNotFoundException` being raised -- which is especially unhelpful
when intending to re-throw an exception.
The docs for `JNIEnv#FindClass(..)` can be found [here][jnienv].
[jnienv]:
https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#:~:text=The%20name%20argument,java/lang/String%22
## Changelog
[Android] [Fixed] - Correctly resolve classes with FindClass(..)
Pull Request resolved: https://github.com/facebook/react-native/pull/34533
Test Plan:
No exact test plan. However, if an exception is thrown during the
rendering process, a fatal `ClassNotFoundException` is raised, rather
than having the error be passed up to the `ReactNativeManager`.
Fixes: facebook/yoga#1120
Reviewed By: amir-shalem
Differential Revision: D39133326
Pulled By: jacdebug
fbshipit-source-id: 86283b7d21aed49ed0e9027b2aef85f0108cdf9a
Summary:
This Pull Request aims at removing the making of reactnativeutilsjni as it is built from the same sources as reactnativejni. It also replaces references to reactnativeutilsjni with reactnativejni.
This should get rid of `reactnativeutilsjni.so` while reusing `reactnativejni.so` in it's place. This should give us some size improvements in the finally built apk.
## Changelog
<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->
[Android] [Changed] - Replaced reactnativeutilsjni with reactnativejni in the build process to reduce size
Pull Request resolved: https://github.com/facebook/react-native/pull/34339
Test Plan:
1. Ran the CMakelist.txt file using CMake and I could see that reactnativeutilsjni.dir is no longer generated with my changes.
2. Built the aar from this branch in Android Studio and build happened successfully.
I am not sure if we could run any more tests. Please let me know in case anymore testing is required and I can do accordingly
Reviewed By: cortinico
Differential Revision: D38400481
Pulled By: genkikondo
fbshipit-source-id: 592736e56441328389ae89135667c336ff8018e6
Summary:
The current implementation of **getDefaultJSExecutorFactory** relies solely on try catch to load the correct .so file for jsc or hermes based on the project configuration.
Relying solely on try catch block and loading jsc even when project is using hermes can lead to launch time crashes especially in monorepo architectures and hybrid apps using both native android and react native.
So we can make use of an additional **ReactInstanceManager :: setJsEngineAsHermes** method that accepts a Boolean argument from the host app while building ReactInstanceManager which can tell which library to load at startup in **ReactInstanceManagerBuilder** which will now have an enhanced getDefaultJSExecutorFactory method that will combine the old logic with the new one to load the dso files.
The code snippet in **ReactInstanceManager** for adding a new setter method:
```
/**
* Sets the jsEngine as JSC or HERMES as per the setJsEngineAsHermes call
* Uses the enum {link JSInterpreter}
* param jsEngine
*/
private void setJSEngine(JSInterpreter jsEngine){
this.jsEngine = jsEngine;
}
/**
* Utility setter to set the required JSEngine as HERMES or JSC
* Defaults to OLD_LOGIC if not called by the host app
* param hermesEnabled
* hermesEnabled = true sets the JS Engine as HERMES and JSC otherwise
*/
public ReactInstanceManagerBuilder setJsEngineAsHermes(boolean hermesEnabled){
if(hermesEnabled){
setJSEngine(JSInterpreter.HERMES);
}
else{
setJSEngine(JSInterpreter.JSC);
}
return this;
}
```
The code snippet for the new logic in **ReactInstanceManagerBuilder**:
1) Setting up the new logic:
Adding a new enum class :
```
public enum JSInterpreter {
OLD_LOGIC,
JSC,
HERMES
}
```
A setter getting boolean value telling whether to use hermes or not and calling a private setter to update the enum variable.
```
/**
* Sets the jsEngine as JSC or HERMES as per the setJsEngineAsHermes call
* Uses the enum {link JSInterpreter}
* param jsEngine
*/
private void setJSEngine(JSInterpreter jsEngine){
this.jsEngine = jsEngine;
}
/**
* Utility setter to set the required JSEngine as HERMES or JSC
* Defaults to OLD_LOGIC if not called by the host app
* param hermesEnabled
* hermesEnabled = true sets the JS Engine as HERMES and JSC otherwise
*/
public ReactInstanceManagerBuilder setJsEngineAsHermes(boolean hermesEnabled){
if(hermesEnabled){
setJSEngine(JSInterpreter.HERMES);
}
else{
setJSEngine(JSInterpreter.JSC);
}
return this;
}
```
2) Modifying the getDefaultJSExecutorFactory method to incorporate the new logic with the old one:
```
private JavaScriptExecutorFactory getDefaultJSExecutorFactory(
String appName, String deviceName, Context applicationContext) {
// Relying solely on try catch block and loading jsc even when
// project is using hermes can lead to launch-time crashes especially in
// monorepo architectures and hybrid apps using both native android
// and react native.
// So we can use the value of enableHermes received by the constructor
// to decide which library to load at launch
// if nothing is specified, use old loading method
// else load the required engine
if (jsEngine == JSInterpreter.OLD_LOGIC) {
try {
// If JSC is included, use it as normal
initializeSoLoaderIfNecessary(applicationContext);
JSCExecutor.loadLibrary();
return new JSCExecutorFactory(appName, deviceName);
} catch (UnsatisfiedLinkError jscE) {
if (jscE.getMessage().contains("__cxa_bad_typeid")) {
throw jscE;
}
HermesExecutor.loadLibrary();
return new HermesExecutorFactory();
}
} else if (jsEngine == JSInterpreter.HERMES) {
HermesExecutor.loadLibrary();
return new HermesExecutorFactory();
} else {
JSCExecutor.loadLibrary();
return new JSCExecutorFactory(appName, deviceName);
}
}
```
### **Suggested changes in any Android App's MainApplication that extends ReactApplication to take advantage of this fix**
```
builder = ReactInstanceManager.builder()
.setApplication(this)
.setJsEngineAsHermes(BuildConfig.HERMES_ENABLED)
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index")
```
where HERMES_ENABLED is a buildConfigField based on the enableHermes flag in build.gradle:
`def enableHermes = project.ext.react.get("enableHermes", true)
`
and then
```
defaultConfig{
if(enableHermes) {
buildConfigField("boolean", "HERMES_ENABLED", "true")
}
else{
buildConfigField("boolean", "HERMES_ENABLED", "false")
}
}
```
Our app was facing a similar issue as listed in this list: **https://github.com/facebook/react-native/issues?q=is%3Aissue+is%3Aopen+DSO**. Which was react-native trying to load jsc even when our project used hermes when a debug build was deployed on a device using android studio play button.
This change can possibly solve many of the issues listed in the list as it solved ours.
## Changelog
[GENERAL] [ADDED] - An enum JSInterpreter in com.facebook.react package:
```
/**
* An enum that specifies the JS Engine to be used in the app
* Old Logic uses the legacy code
* JSC/HERMES loads the respective engine using the revamped logic
*/
public enum JSInterpreter {
OLD_LOGIC,
JSC,
HERMES
}
```
[GENERAL] [ADDED] - An enum variable storing the default value of Js Engine loading mechanism in ReactInstanceManagerBuilder:
```
private JSInterpreter jsEngine = JSInterpreter.OLD_LOGIC;
```
[GENERAL] [ADDED] - A new setter method and a helper method to set the js engine in ReactInstanceManagerBuilder:
```
/**
* Sets the jsEngine as JSC or HERMES as per the setJsEngineAsHermes call
* Uses the enum {link JSInterpreter}
* param jsEngine
*/
private void setJSEngine(JSInterpreter jsEngine){
this.jsEngine = jsEngine;
}
/**
* Utility setter to set the required JSEngine as HERMES or JSC
* Defaults to OLD_LOGIC if not called by the host app
* param hermesEnabled
* hermesEnabled = true sets the JS Engine as HERMES and JSC otherwise
*/
public ReactInstanceManagerBuilder setJsEngineAsHermes(boolean hermesEnabled){
if(hermesEnabled){
setJSEngine(JSInterpreter.HERMES);
}
else{
setJSEngine(JSInterpreter.JSC);
}
return this;
}
```
[GENERAL] [ADDED] - Modified **getDefaultJSExecutorFactory** method
```
private JavaScriptExecutorFactory getDefaultJSExecutorFactory(
String appName, String deviceName, Context applicationContext) {
// Relying solely on try catch block and loading jsc even when
// project is using hermes can lead to launch-time crashes especially in
// monorepo architectures and hybrid apps using both native android
// and react native.
// So we can use the value of enableHermes received by the constructor
// to decide which library to load at launch
// if nothing is specified, use old loading method
// else load the required engine
if (jsEngine == JSInterpreter.OLD_LOGIC) {
try {
// If JSC is included, use it as normal
initializeSoLoaderIfNecessary(applicationContext);
JSCExecutor.loadLibrary();
return new JSCExecutorFactory(appName, deviceName);
} catch (UnsatisfiedLinkError jscE) {
if (jscE.getMessage().contains("__cxa_bad_typeid")) {
throw jscE;
}
HermesExecutor.loadLibrary();
return new HermesExecutorFactory();
}
} else if (jsEngine == JSInterpreter.HERMES) {
HermesExecutor.loadLibrary();
return new HermesExecutorFactory();
} else {
JSCExecutor.loadLibrary();
return new JSCExecutorFactory(appName, deviceName);
}
}
```
Pull Request resolved: https://github.com/facebook/react-native/pull/33952
Test Plan:
The testing for this change might be tricky but can be done by following the reproduction steps in the issues related to DSO loading here: https://github.com/facebook/react-native/issues?q=is%3Aissue+is%3Aopen+DSO
Generally, the app will not crash anymore on deploying debug using android studio if we are removing libjsc and its related libraries in **packagingOptions** in build.gradle and using hermes in the project.
It can be like:
```
packagingOptions {
if (enableHermes) {
exclude "**/libjsc*.so"
}
}
```
Reviewed By: lunaleaps
Differential Revision: D37191981
Pulled By: cortinico
fbshipit-source-id: c528ead126939f1d788af7523f3798ed2a14f36e
Summary:
In https://github.com/facebook/react-native/pull/32695, the `Performance.now()` implementation changed to use unix epoch timestamps instead of a monotonic clock.
This is problematic, because it means that performance measurements get skewed if the device clock changes between two measurements.
With this change, the clock is now monotonic (and the implementation stays consistent between platforms).
More details and repro steps can be found in [this issue](https://github.com/facebook/react-native/issues/33977)
Closes https://github.com/facebook/react-native/issues/33977
## Changelog
[General] [Fixed] - Use monotonic clock for performance.now()
Pull Request resolved: https://github.com/facebook/react-native/pull/33983
Test Plan:
Run on iOS and Android:
```
const now = global.performance.now()
console.log(`${Platform.OS}: ${now}`)
```
Reviewed By: JoshuaGross, cipolleschi
Differential Revision: D37066999
Pulled By: dmitryrykun
fbshipit-source-id: 298547bf39faea1b025c17ff2d2e1a03f929865b
Summary:
Currently, we build Hermes by specifying the Cmake flag `-B ./hermes`. That means
that the output out the build is going to be placed along side the source code.
This is fine, as long as the user doesn't use the `REACT_NATIVE_OVERRIDE_HERMES_DIR`,
which is used inside the Hermes CI. In that case, the source location of Hermes can be
changed, leading to scenarios where `hermesc` can't be found.
Here I'm changing the flag to be `-B $buildDir/hermes`. Therefore the build output
will always be located within the `./ReactAndroid/hermes-engine/build` folder.
This is a more robust solution as the build output will be encapsulated within the
`build/` folder.
Changelog:i
[Internal] [Changed] - Update the hermesc output to be inside the $buildDir
Reviewed By: cipolleschi
Differential Revision: D35964402
fbshipit-source-id: aa7e0775b282897d5a99c1c46265884d19c5f289
Summary:
The `notifyNativeGestureEnded` API is added to notify user gesture ended, so that any optimization we had during handling the gesture can be restored.
It's possible that when the gesture finishes, the RootView is already unmounted from the native side. This might happen when user starts a gesture that caused leave of the RN screen, or close the app.
Changelog:
[Android][Internal] - Avoid NPE for gesture notifier
Reviewed By: javache
Differential Revision: D35902523
fbshipit-source-id: 9bb5819a53dd053290031eebaae1b8f0318ae534
Summary:
This diff updates the CMake command used for configuring the Hermes build
from `cmake` from $PATH to the `cmake` bundled with the Android SDK.
If not found, fallsback to the previous behavior.
This relaxes the requirement of having to ask our users to install CMake
in their CLIs.
Changelog:
[Internal] [Changed] - Use Android SDK version of CMake rather than an external one
Reviewed By: neildhar
Differential Revision: D35931306
fbshipit-source-id: 8d6c554e5e9040e3bd4fed5f72fbdb0eb61d745a
Summary:
Refactor of TouchTargetHelper.findTargetPathAndCoordinatesForTouch to avoid unnecessary lookup of views during the dispatching of Hover Events
changelog: [internal] internal
Reviewed By: lunaleaps, mdvacca
Differential Revision: D32296003
fbshipit-source-id: 93834c37331ad5d75645a5665a1c8c3d965765fb
Summary:
WHen porting TurboModules or adding new TurboModules, ReactModuleSpecProcessor may fail during buck build, and when the failure is caused by typeElement.getAnnotation, no useful information gets collected, making it difficult to debug.
So here I am adding a try & catch so we can get useful debugging info.
Changelog: [Internal]
Reviewed By: RSNara
Differential Revision: D35767207
fbshipit-source-id: 7e1f9dfbfd31339ab37af19c51d85085e100955a
Summary:
This diff allows to customize the Hermes version exposed by the VM with
a version provided by React Native. This will make clearer that a specific
version of Hermes was built at a specific point of the RN release process.
Changelog:
[Internal] [Changed] - Customize the Hermes version using the RN one
Reviewed By: neildhar
Differential Revision: D35820268
fbshipit-source-id: 3e76db921c12a599743fb9312f52edd06d223bad
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/33645
With React 18, we now need to allow users on Fabric to opt-in for Concurrent Root.
This commit adds a new method that can be called on the ReactActivityDelegate
that can be used to set the `concurrentRoot` flag on the `initialProps` on the Render.
Changelog:
[Android] [Added] - Expose an API to enable Concurrent Root on Android
Reviewed By: mdvacca
Differential Revision: D35614879
fbshipit-source-id: 2de83e8115d3748c0346cdec6f31b2ab1f899478
Summary:
D34687371 (https://github.com/facebook/react-native/commit/7b5b114d578142d18bf4a7a5279b179a9ac8d958) unfortunately caused a regression with UIAutomator, where it would no longer be able to see any Views that have the ReactAccessibilityDelegate attached to them. This was because the delegate was changed to extend ExploreByTouchHelper which implements its own default AccessibilityNodeProvider, which does nothing in the case of a view without any virtual children.
This diff simply *only* uses the node provider if the view in question has virtual children, otherwise defaulting to the standard behavior from the View class.
Changelog:
[Android][Fixed] - Fixed issue where any node with an AccessibilityDelegate set (which was any node with any accessibility propoerty), was using ExploreByTouchHelper's built in AccessibilityNodeProvider, and not properly populating their AccessibilityNodeInfo's, leading to focus issues and issues with automated test services like UIAutomator.
Reviewed By: kacieb
Differential Revision: D35601320
fbshipit-source-id: 92e009c6e8b4ddcab860e2c91e6bd1a8f95359f0
Summary:
Changelog:
[Android][Fixed] - Fix Extras usage in Android implementation of Linking.sendIntent()
The implementation of sendIntent() has a bug in a way it uses extras map.
From JS layer the API sends and array of map, where each map contains exactly 2 entries: {"key" -> "name_of_extra_to_use", "value" -> value_of_extra_to_use}
However Java parsing was just picking a random pair out of this map and was sending it as extra.
Most frequently the result was "value" -> value_of_extra_to_use in Intent instead of name_of_extra_to_use -> value_of_extra_to_use
This diff fixes the problem
Reviewed By: lunaleaps
Differential Revision: D35516496
fbshipit-source-id: 7da0a1cb3b8aa30463004dbb47008c83d8e95bd1
Summary:
This diff fixes a NullPointerException when disaptching events while the SurfaceMountingManager is being destroyed
changelog: [android] android
Reviewed By: cortinico
Differential Revision: D35559550
fbshipit-source-id: c07f74493384fb1b306338ec1bc8b96f1b6f1f41
Summary: Changelog: [Internal] - Fix pointer event dispatch to also fire enter/leave for ancestors in the hit path. Compared the event order with web on the RNTester W3C pointer example
Reviewed By: appden
Differential Revision: D35403076
fbshipit-source-id: 726e45e49a901b1d97ad3e20f5898701fd1f763b
Summary:
As we introduced KGP inside `ReactAndroid` (cc ShikaSD), we now need to specify a version for it (as users will consume that build on Android New Architecture.
Currently, the version is loaded in the RN `rootProject` which is not available on user's project. I'm cleaning this up.
## Changelog
[Internal] - Do not specify a Kotlin version in the RN rootProject
Pull Request resolved: https://github.com/facebook/react-native/pull/33589
Test Plan:
Tested on a nightly version with
```
npx react-native init RNNightly --version nightly
```
Reviewed By: mdvacca
Differential Revision: D35476777
Pulled By: cortinico
fbshipit-source-id: 5a819ef5fa9a6886d7b7b683f31d59cb05a49f29
Summary:
This is a follow up to my previous diff. It applies the same customization for M1 users to the :ReactAndroid:hermes-engine build.
The two diffs are split so the first one can be cherry-picked into 0.68.1 if needed.
Changelog:
[Android] [Fixed] - Improve support for Android users on M1 machine
Reviewed By: mdvacca
Differential Revision: D35468658
fbshipit-source-id: c07822f6708f872456971378f44257f6c1e967ee
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/33588
Currently users on M1 machine can't use the New Architecture correctly as they will get build failures when building the native code.
This Diff fixes it by automatically recognizing the host architecture and switching to NDK 24 if user is runnign on `aarch64`
Changelog:
[Android] [Fixed] - Improve support for Android users on M1 machine
Reviewed By: mdvacca
Differential Revision: D35468252
fbshipit-source-id: b73f5262b9408f04f3ae4fd26458a4d17c1ec29a