From 67c3ad4e6a1847cbac43115b01f72cc5c8932a61 Mon Sep 17 00:00:00 2001 From: Toby Cox Date: Fri, 16 Feb 2018 17:28:35 -0800 Subject: [PATCH] Fix pinch crash in touch-responsive views. Summary: Fork and rebase of gillessed's PR https://github.com/facebook/react-native/pull/13166 which has gotten stale. From original PR: Motivation (required) Multiple react native developer (including myself) have run into a crash with the react-native-photo-view library (and possibly others). The common solution to this problem lies in the underlying java code, and thus requires a change in the react native source. The stack trace I am getting is the same as listed here alwx/react-native-photo-view#15. There was a PR to fix this (#12085) but it was closed. In response to the comments there, in my PR, I do log the exceptions. I don't think we can get any closer to the exception because in the next level of the stack trace, we are in the android sdk code. Looking at some stack overflow pages and the android bug tracker, it seems that this is the common solution to this bug, and does not cause any impact any functionality. https://code.google.com/p/android/issues/list?can=1&q=pointerindex+out+of+range&colspec=ID+Status+Priority+Owner+Summary+Stars+Reporter+Opened&cells=tiles Test Plan (required) I have manually tested this by compiling react native android from source and have confirmed the exception still gets hit and logged, but does not cause the app to terminate. Closes https://github.com/facebook/react-native/pull/17167 Differential Revision: D7014296 Pulled By: hramos fbshipit-source-id: 06b4a31062a591b726d2021e877d16f49881dcfd --- .../react/views/drawer/ReactDrawerLayout.java | 16 +++++++++++--- .../scroll/ReactHorizontalScrollView.java | 22 ++++++++++++++----- .../react/views/scroll/ReactScrollView.java | 19 +++++++++++----- .../react/views/viewpager/ReactViewPager.java | 16 +++++++++++--- 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayout.java b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayout.java index abdb4a04d4e..cdb0265e26e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayout.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayout.java @@ -11,10 +11,12 @@ package com.facebook.react.views.drawer; import android.support.v4.widget.DrawerLayout; import android.view.Gravity; +import android.util.Log; import android.view.MotionEvent; import android.view.View; import com.facebook.react.bridge.ReactContext; +import com.facebook.react.common.ReactConstants; import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.events.NativeGestureUtil; @@ -34,10 +36,18 @@ import com.facebook.react.uimanager.events.NativeGestureUtil; @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - if (super.onInterceptTouchEvent(ev)) { - NativeGestureUtil.notifyNativeGestureStarted(this, ev); - return true; + try { + if (super.onInterceptTouchEvent(ev)) { + NativeGestureUtil.notifyNativeGestureStarted(this, ev); + return true; + } + } catch (IllegalArgumentException e) { + // Log and ignore the error. This seems to be a bug in the android SDK and + // this is the commonly accepted workaround. + // https://tinyurl.com/mw6qkod (Stack Overflow) + Log.w(ReactConstants.TAG, "Error intercepting touch event.", e); } + return false; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index 38371436b88..ebcd2d50110 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -17,10 +17,13 @@ import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.support.v4.view.ViewCompat; +import android.graphics.drawable.LayerDrawable; +import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.HorizontalScrollView; import com.facebook.infer.annotation.Assertions; +import com.facebook.react.common.ReactConstants; import com.facebook.react.uimanager.MeasureSpecAssertions; import com.facebook.react.uimanager.ReactClippingViewGroup; import com.facebook.react.uimanager.ReactClippingViewGroupHelper; @@ -140,12 +143,19 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements return false; } - if (super.onInterceptTouchEvent(ev)) { - NativeGestureUtil.notifyNativeGestureStarted(this, ev); - ReactScrollViewHelper.emitScrollBeginDragEvent(this); - mDragging = true; - enableFpsListener(); - return true; + try { + if (super.onInterceptTouchEvent(ev)) { + NativeGestureUtil.notifyNativeGestureStarted(this, ev); + ReactScrollViewHelper.emitScrollBeginDragEvent(this); + mDragging = true; + enableFpsListener(); + return true; + } + } catch (IllegalArgumentException e) { + // Log and ignore the error. This seems to be a bug in the android SDK and + // this is the commonly accepted workaround. + // https://tinyurl.com/mw6qkod (Stack Overflow) + Log.w(ReactConstants.TAG, "Error intercepting touch event.", e); } return false; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index a9c7960cf14..509964ceb13 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -190,12 +190,19 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou return false; } - if (super.onInterceptTouchEvent(ev)) { - NativeGestureUtil.notifyNativeGestureStarted(this, ev); - ReactScrollViewHelper.emitScrollBeginDragEvent(this); - mDragging = true; - enableFpsListener(); - return true; + try { + if (super.onInterceptTouchEvent(ev)) { + NativeGestureUtil.notifyNativeGestureStarted(this, ev); + ReactScrollViewHelper.emitScrollBeginDragEvent(this); + mDragging = true; + enableFpsListener(); + return true; + } + } catch (IllegalArgumentException e) { + // Log and ignore the error. This seems to be a bug in the android SDK and + // this is the commonly accepted workaround. + // https://tinyurl.com/mw6qkod (Stack Overflow) + Log.w(ReactConstants.TAG, "Error intercepting touch event.", e); } return false; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java index 9a76bace545..7d99e272a40 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java @@ -11,10 +11,12 @@ package com.facebook.react.views.viewpager; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; +import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import com.facebook.react.bridge.ReactContext; +import com.facebook.react.common.ReactConstants; import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.uimanager.events.NativeGestureUtil; @@ -176,10 +178,18 @@ public class ReactViewPager extends ViewPager { return false; } - if (super.onInterceptTouchEvent(ev)) { - NativeGestureUtil.notifyNativeGestureStarted(this, ev); - return true; + try { + if (super.onInterceptTouchEvent(ev)) { + NativeGestureUtil.notifyNativeGestureStarted(this, ev); + return true; + } + } catch (IllegalArgumentException e) { + // Log and ignore the error. This seems to be a bug in the android SDK and + // this is the commonly accepted workaround. + // https://tinyurl.com/mw6qkod (Stack Overflow) + Log.w(ReactConstants.TAG, "Error intercepting touch event.", e); } + return false; }