-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Android: Fix crash when WindowInsets is null on ReactRootView #32989
Conversation
…oid ReactRootView checkForKeyboardEvents method
Base commit: 384e1a0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change looks sane to me. Also from the documentation:
https://developer.android.com/reference/android/view/View#getRootWindowInsets()
WindowInsets from the top of the view hierarchy or null if View is detached
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation is odd here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation fixed ;)
@@ -826,10 +827,13 @@ private void checkForKeyboardEvents() { | |||
getRootView().getWindowVisibleDisplayFrame(mVisibleViewArea); | |||
int notchHeight = 0; | |||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { | |||
DisplayCutout displayCutout = getRootView().getRootWindowInsets().getDisplayCutout(); | |||
WindowInsets insets = getRootView().getRootWindowInsets(); | |||
if (insets != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: That's why we need Kotlin :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...and million other reasons too 😅
Base commit: 384e1a0 |
@ShikaSD has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
This pull request was successfully merged by @enahum in 6239e2f. When will my fix make it into a release? | Upcoming Releases |
Summary: Fixes a potential crash was introduced by #30919 that aimed to get the keyboard height on devices with a Notch. The problem is that it considers that any ReactRootView will have an insets available. When using [react-native-navigation](https://github.com/wix/react-native-navigation) and assigning a Navigation button to the TopBar as a component, the component gets registered as a RootView but won't have any insets attach to the view. [getRootWindowInsets()](https://developer.android.com/reference/android/view/View#getRootWindowInsets()) in fact return a `WindowInset` only available if the view is attached, so when executing `checkForKeyboardEvents` method from ReactRootView, is trying to access the `DisplayCutout` of a null object, leading to a crash. ## Changelog [Android] [Fixed] - Fix potential crash if ReactRootView does not have insets attached. Pull Request resolved: #32989 Test Plan: Without the code change: Notice how the second screen being push contains a React Component on the top right of the navigation bar, and when component is unmounted (going back) the app crashes. https://user-images.githubusercontent.com/6757047/151558235-39b9a8b5-be73-4c31-8053-02ce188637b8.mp4 crash log ``` 2022-01-28 10:27:52.902 15600-15600/com.mattermost.rnbeta E/AndroidRuntime: FATAL EXCEPTION: main Process: com.mattermost.rnbeta, PID: 15600 java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.DisplayCutout android.view.WindowInsets.getDisplayCutout()' on a null object reference at com.facebook.react.ReactRootView$CustomGlobalLayoutListener.checkForKeyboardEvents(ReactRootView.java:778) at com.facebook.react.ReactRootView$CustomGlobalLayoutListener.onGlobalLayout(ReactRootView.java:769) at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:1061) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3214) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2143) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8665) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1037) at android.view.Choreographer.doCallbacks(Choreographer.java:845) at android.view.Choreographer.doFrame(Choreographer.java:780) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) ``` After applying the patch which is only a null check validation and does not change any previous behavior https://user-images.githubusercontent.com/6757047/151558429-9ff1a608-abb6-4168-8db9-df0c3c71d79e.mp4 Reviewed By: cortinico Differential Revision: D33844955 Pulled By: ShikaSD fbshipit-source-id: ed5579ad3afeed009c61cc1851eee45c70087cf5
Summary: Fixes a potential crash was introduced by #30919 that aimed to get the keyboard height on devices with a Notch. The problem is that it considers that any ReactRootView will have an insets available. When using [react-native-navigation](https://github.com/wix/react-native-navigation) and assigning a Navigation button to the TopBar as a component, the component gets registered as a RootView but won't have any insets attach to the view. [getRootWindowInsets()](https://developer.android.com/reference/android/view/View#getRootWindowInsets()) in fact return a `WindowInset` only available if the view is attached, so when executing `checkForKeyboardEvents` method from ReactRootView, is trying to access the `DisplayCutout` of a null object, leading to a crash. ## Changelog [Android] [Fixed] - Fix potential crash if ReactRootView does not have insets attached. Pull Request resolved: #32989 Test Plan: Without the code change: Notice how the second screen being push contains a React Component on the top right of the navigation bar, and when component is unmounted (going back) the app crashes. https://user-images.githubusercontent.com/6757047/151558235-39b9a8b5-be73-4c31-8053-02ce188637b8.mp4 crash log ``` 2022-01-28 10:27:52.902 15600-15600/com.mattermost.rnbeta E/AndroidRuntime: FATAL EXCEPTION: main Process: com.mattermost.rnbeta, PID: 15600 java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.DisplayCutout android.view.WindowInsets.getDisplayCutout()' on a null object reference at com.facebook.react.ReactRootView$CustomGlobalLayoutListener.checkForKeyboardEvents(ReactRootView.java:778) at com.facebook.react.ReactRootView$CustomGlobalLayoutListener.onGlobalLayout(ReactRootView.java:769) at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:1061) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3214) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2143) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8665) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1037) at android.view.Choreographer.doCallbacks(Choreographer.java:845) at android.view.Choreographer.doFrame(Choreographer.java:780) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) ``` After applying the patch which is only a null check validation and does not change any previous behavior https://user-images.githubusercontent.com/6757047/151558429-9ff1a608-abb6-4168-8db9-df0c3c71d79e.mp4 Reviewed By: cortinico Differential Revision: D33844955 Pulled By: ShikaSD fbshipit-source-id: ed5579ad3afeed009c61cc1851eee45c70087cf5
…ok#32989) Summary: Fixes a potential crash was introduced by facebook#30919 that aimed to get the keyboard height on devices with a Notch. The problem is that it considers that any ReactRootView will have an insets available. When using [react-native-navigation](https://github.com/wix/react-native-navigation) and assigning a Navigation button to the TopBar as a component, the component gets registered as a RootView but won't have any insets attach to the view. [getRootWindowInsets()](https://developer.android.com/reference/android/view/View#getRootWindowInsets()) in fact return a `WindowInset` only available if the view is attached, so when executing `checkForKeyboardEvents` method from ReactRootView, is trying to access the `DisplayCutout` of a null object, leading to a crash. ## Changelog [Android] [Fixed] - Fix potential crash if ReactRootView does not have insets attached. Pull Request resolved: facebook#32989 Test Plan: Without the code change: Notice how the second screen being push contains a React Component on the top right of the navigation bar, and when component is unmounted (going back) the app crashes. https://user-images.githubusercontent.com/6757047/151558235-39b9a8b5-be73-4c31-8053-02ce188637b8.mp4 crash log ``` 2022-01-28 10:27:52.902 15600-15600/com.mattermost.rnbeta E/AndroidRuntime: FATAL EXCEPTION: main Process: com.mattermost.rnbeta, PID: 15600 java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.DisplayCutout android.view.WindowInsets.getDisplayCutout()' on a null object reference at com.facebook.react.ReactRootView$CustomGlobalLayoutListener.checkForKeyboardEvents(ReactRootView.java:778) at com.facebook.react.ReactRootView$CustomGlobalLayoutListener.onGlobalLayout(ReactRootView.java:769) at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:1061) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3214) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2143) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8665) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1037) at android.view.Choreographer.doCallbacks(Choreographer.java:845) at android.view.Choreographer.doFrame(Choreographer.java:780) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) ``` After applying the patch which is only a null check validation and does not change any previous behavior https://user-images.githubusercontent.com/6757047/151558429-9ff1a608-abb6-4168-8db9-df0c3c71d79e.mp4 Reviewed By: cortinico Differential Revision: D33844955 Pulled By: ShikaSD fbshipit-source-id: ed5579ad3afeed009c61cc1851eee45c70087cf5
Summary
Fixes a potential crash was introduced by #30919 that aimed to get the keyboard height on devices with a Notch. The problem is that it considers that any ReactRootView will have an insets available.
When using react-native-navigation and assigning a Navigation button to the TopBar as a component, the component gets registered as a RootView but won't have any insets attach to the view.
getRootWindowInsets() in fact return a
WindowInset
only available if the view is attached, so when executingcheckForKeyboardEvents
method from ReactRootView, is trying to access theDisplayCutout
of a null object, leading to a crash.Changelog
[Android] [Fixed] - Fix potential crash if ReactRootView does not have insets attached.
Test Plan
Without the code change: Notice how the second screen being push contains a React Component on the top right of the navigation bar, and when component is unmounted (going back) the app crashes.
rn67-crash.1.mp4
crash log
After applying the patch which is only a null check validation and does not change any previous behavior
rn67-fix.1.mp4