Skip to content

Commit 4cdc2c4

Browse files
enahumfacebook-github-bot
authored andcommitted
fix: ReactRootView checkForKeyboardEvents to check if rootInsets are set (#35869)
Summary: react-native-navigation allows to register React components to be included in the navigation top bar as buttons, the way this work is by using the AppRegistry. When the ViewTreeObserver executes the `CustomGlobalLayout` we are checking for the RootWindowInsets in the `checkKeyboardEvents` which in the case for the top bar component it returns null and the **WindowInsetsCompat.toWindowInsetsCompat** function throws if the insets are null causing the app to crash. Interestingly in the function `checkForKeyboardEventsLegacy` the null value is being checked, so I guess it was overlooked in the newer function. ## Changelog [ANDROID] [FIXED] - Fix ReactRootView crash when root view window insets are null Pull Request resolved: #35869 Test Plan: The following videos show how the app crashes as soon as we attempt to pop a screen that contains a react component as a button in the navigation top bar and how it correctly pops to the previous screen after applying the fix | Crash | Fix | | -- | -- | | https://user-images.githubusercontent.com/6757047/213116971-fe693989-f978-438c-b8f9-fc56f2a477c8.mp4 | https://user-images.githubusercontent.com/6757047/213118352-fe258f28-07aa-4d17-98d2-97136464ffd5.mp4 | Reviewed By: cipolleschi Differential Revision: D42580156 Pulled By: cortinico fbshipit-source-id: 4dbd656d7c8148df67668a2a50913206bc35c07f
1 parent 0c150b2 commit 4cdc2c4

File tree

2 files changed

+41
-37
lines changed

2 files changed

+41
-37
lines changed

ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java

+34-32
Original file line numberDiff line numberDiff line change
@@ -923,38 +923,40 @@ public void onGlobalLayout() {
923923
private void checkForKeyboardEvents() {
924924
getRootView().getWindowVisibleDisplayFrame(mVisibleViewArea);
925925
WindowInsets rootInsets = getRootView().getRootWindowInsets();
926-
WindowInsetsCompat compatRootInsets = WindowInsetsCompat.toWindowInsetsCompat(rootInsets);
927-
928-
boolean keyboardIsVisible = compatRootInsets.isVisible(WindowInsetsCompat.Type.ime());
929-
if (keyboardIsVisible != mKeyboardIsVisible) {
930-
mKeyboardIsVisible = keyboardIsVisible;
931-
932-
if (keyboardIsVisible) {
933-
Insets imeInsets = compatRootInsets.getInsets(WindowInsetsCompat.Type.ime());
934-
Insets barInsets = compatRootInsets.getInsets(WindowInsetsCompat.Type.systemBars());
935-
int height = imeInsets.bottom - barInsets.bottom;
936-
937-
int softInputMode = ((Activity) getContext()).getWindow().getAttributes().softInputMode;
938-
int screenY =
939-
softInputMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING
940-
? mVisibleViewArea.bottom - height
941-
: mVisibleViewArea.bottom;
942-
943-
sendEvent(
944-
"keyboardDidShow",
945-
createKeyboardEventPayload(
946-
PixelUtil.toDIPFromPixel(screenY),
947-
PixelUtil.toDIPFromPixel(mVisibleViewArea.left),
948-
PixelUtil.toDIPFromPixel(mVisibleViewArea.width()),
949-
PixelUtil.toDIPFromPixel(height)));
950-
} else {
951-
sendEvent(
952-
"keyboardDidHide",
953-
createKeyboardEventPayload(
954-
PixelUtil.toDIPFromPixel(mLastHeight),
955-
0,
956-
PixelUtil.toDIPFromPixel(mVisibleViewArea.width()),
957-
0));
926+
if (rootInsets != null) {
927+
WindowInsetsCompat compatRootInsets = WindowInsetsCompat.toWindowInsetsCompat(rootInsets);
928+
929+
boolean keyboardIsVisible = compatRootInsets.isVisible(WindowInsetsCompat.Type.ime());
930+
if (keyboardIsVisible != mKeyboardIsVisible) {
931+
mKeyboardIsVisible = keyboardIsVisible;
932+
933+
if (keyboardIsVisible) {
934+
Insets imeInsets = compatRootInsets.getInsets(WindowInsetsCompat.Type.ime());
935+
Insets barInsets = compatRootInsets.getInsets(WindowInsetsCompat.Type.systemBars());
936+
int height = imeInsets.bottom - barInsets.bottom;
937+
938+
int softInputMode = ((Activity) getContext()).getWindow().getAttributes().softInputMode;
939+
int screenY =
940+
softInputMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING
941+
? mVisibleViewArea.bottom - height
942+
: mVisibleViewArea.bottom;
943+
944+
sendEvent(
945+
"keyboardDidShow",
946+
createKeyboardEventPayload(
947+
PixelUtil.toDIPFromPixel(screenY),
948+
PixelUtil.toDIPFromPixel(mVisibleViewArea.left),
949+
PixelUtil.toDIPFromPixel(mVisibleViewArea.width()),
950+
PixelUtil.toDIPFromPixel(height)));
951+
} else {
952+
sendEvent(
953+
"keyboardDidHide",
954+
createKeyboardEventPayload(
955+
PixelUtil.toDIPFromPixel(mLastHeight),
956+
0,
957+
PixelUtil.toDIPFromPixel(mVisibleViewArea.width()),
958+
0));
959+
}
958960
}
959961
}
960962
}

packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt

+7-5
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,16 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
2222
val targetName = variant.name.replaceFirstChar { it.uppercase() }
2323
val targetPath = variant.name
2424

25-
// React js bundle directories
25+
// Resources: generated/assets/react/<variant>/index.android.bundle
2626
val resourcesDir = File(buildDir, "generated/res/react/$targetPath")
27-
// Bundle: generated/assets/react/path/index.android.bundle
27+
// Bundle: generated/assets/react/<variant>/index.android.bundle
2828
val jsBundleDir = File(buildDir, "generated/assets/react/$targetPath")
29-
// Sourcemap: generated/sourcemaps/react/path/index.android.bundle.map
29+
// Sourcemap: generated/sourcemaps/react/<variant>/index.android.bundle.map
3030
val jsSourceMapsDir = File(buildDir, "generated/sourcemaps/react/$targetPath")
31-
// Intermediate packager: intermediates/sourcemaps/react/path/index.android.bundle.packager.map
32-
// Intermediate compiler: intermediates/sourcemaps/react/path/index.android.bundle.compiler.map
31+
// Intermediate packager:
32+
// intermediates/sourcemaps/react/<variant>/index.android.bundle.packager.map
33+
// Intermediate compiler:
34+
// intermediates/sourcemaps/react/<variant>/index.android.bundle.compiler.map
3335
val jsIntermediateSourceMapsDir = File(buildDir, "intermediates/sourcemaps/react/$targetPath")
3436

3537
// The location of the cli.js file for React Native

0 commit comments

Comments
 (0)