Skip to content

Commit c44e7e7

Browse files
authored
fix: OverKeyboardView crash (#913)
## 📜 Description Wrapped touch events in `try`/`catch`. ## 💡 Motivation and Context The problem stems from the fact, that we are trying to cast `ViewRootImpl` to `ViewGroup` (viewrootimpl cannot be cast to android.view.viewgroup). Basically it happens when touch gets propagated until `RootView` and wasn't handled earlier. Such thing can happen when: - view is not fully laid out but it already handles a touch; - view is not stretched to full screen and you touch area that doesn't belong to `OverKeyboardView` (fixed in #863) I was aware about that issue (especially on Fabric) and decided not to fix it - the main motivation was to stretch view to full screen on Fabric. However now, when view gets stretched we still have a small race condition when users click fast (i. e. view is not laid out but user already pass a touch). I don't know a proper fix for this problem, and for me it looks like it can be OS scheduling/management which can not be fixed because I don't have an access to it 😅 So in this PR I simply wrap the touch handling in `try`/`catch`. If touch can not be handled then it's better to silently fail instead of crashing the app. Closes #884 ## 📢 Changelog <!-- High level overview of important changes --> <!-- For example: fixed status bar manipulation; added new types declarations; --> <!-- If your changes don't affect one of platform/language below - then remove this platform/language --> ### Android - wrapped `handleTouchEvent` calls inside `try`/`catch` block to prevent a crash; ## 🤔 How Has This Been Tested? Tested manually on Medium Phone API 35. ## 📸 Screenshots (if appropriate): https://github.com/user-attachments/assets/9ffa684d-ddb7-46e5-b143-d526ab680d28 ## 📝 Checklist - [x] CI successfully passed - [x] I added new mocks and corresponding unit-tests if library API was changed
1 parent 581e377 commit c44e7e7

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

android/src/main/java/com/reactnativekeyboardcontroller/views/overlay/OverKeyboardViewGroup.kt

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ import com.facebook.react.uimanager.events.EventDispatcher
1818
import com.facebook.react.views.view.ReactViewGroup
1919
import com.reactnativekeyboardcontroller.extensions.dp
2020
import com.reactnativekeyboardcontroller.extensions.getDisplaySize
21+
import com.reactnativekeyboardcontroller.log.Logger
22+
23+
private val TAG = OverKeyboardHostView::class.qualifiedName
2124

2225
@SuppressLint("ViewConstructor")
2326
class OverKeyboardHostView(
@@ -140,17 +143,29 @@ class OverKeyboardRootViewGroup(
140143
// region Touch events handling
141144
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
142145
eventDispatcher?.let { eventDispatcher ->
143-
jsTouchDispatcher.handleTouchEvent(event, eventDispatcher)
144-
jsPointerDispatcher?.handleMotionEventCompat(event, eventDispatcher, true)
146+
try {
147+
jsTouchDispatcher.handleTouchEvent(event, eventDispatcher)
148+
jsPointerDispatcher?.handleMotionEventCompat(event, eventDispatcher, true)
149+
} catch (
150+
@Suppress("detekt:TooGenericExceptionCaught") e: RuntimeException,
151+
) {
152+
Logger.w(TAG, "Can not handle touch event", e)
153+
}
145154
}
146155
return super.onInterceptTouchEvent(event)
147156
}
148157

149158
@SuppressLint("ClickableViewAccessibility")
150159
override fun onTouchEvent(event: MotionEvent): Boolean {
151160
eventDispatcher?.let { eventDispatcher ->
152-
jsTouchDispatcher.handleTouchEvent(event, eventDispatcher)
153-
jsPointerDispatcher?.handleMotionEventCompat(event, eventDispatcher, false)
161+
try {
162+
jsTouchDispatcher.handleTouchEvent(event, eventDispatcher)
163+
jsPointerDispatcher?.handleMotionEventCompat(event, eventDispatcher, false)
164+
} catch (
165+
@Suppress("detekt:TooGenericExceptionCaught") e: RuntimeException,
166+
) {
167+
Logger.w(TAG, "Can not handle touch event", e)
168+
}
154169
}
155170
super.onTouchEvent(event)
156171
// In case when there is no children interested in handling touch event, we return true from

0 commit comments

Comments
 (0)