[Bug] Crash on multi touch interaction and legend


#1

Hello guys,

I have discovered a crash in the library for android platforms when the user interacts with the graphs.

So I’ve created a graph that can be panned, and zoomed, on the x axis, and everything worked . After that I’ve added a legend to the graphs and that worked too, with interaction, panning, zooming on graphs and all that.

But I have discovered that, if I repeatedly click at the same time on the legend and on the graph, the library crashes. This is the stack for that.

java.lang.IllegalArgumentException: pointerIndex out of range
            at android.view.MotionEvent.nativeGetAxisValue(Native Method)
            at android.view.MotionEvent.getX(MotionEvent.java:2069)
            at android.support.v4.view.MotionEventCompatEclair.getX(MotionEventCompatEclair.java:32)
            at android.support.v4.view.MotionEventCompat$EclairMotionEventVersionImpl.getX(MotionEventCompat.java:91)
            at android.support.v4.view.MotionEventCompat.getX(MotionEventCompat.java:219)
            at android.support.v4.view.ViewPager.onInterceptTouchEvent(ViewPager.java:1834)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1858)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2054)
            at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1503)
            at android.app.Activity.dispatchTouchEvent(Activity.java:2486)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2002)
            at android.view.View.dispatchPointerEvent(View.java:7687)
            at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4223)
            at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4118)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3692)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3742)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3711)
            at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3796)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3719)
            at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3853)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3692)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3742)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3711)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3719)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3692)
            at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5784)
            at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5757)
            at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5720)
            at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5862)
            at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:211)
            at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
            at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:198)
            at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:5839)
            at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:5891)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:786)
            at android.view.Choreographer.doCallbacks(Choreographer.java:586)
            at android.view.Choreographer.doFrame(Choreographer.java:544)
            at android.view.Choreographer$FrameDisplayEventRe

I have discovered a workaround for this, until a fix will be made in the library, for everyone who has this issue.

The idea, is to intercept the touch events before they are received by the shinobi library, and if something is not ok, just catch the exeption before it becomes fatal.

In order to do this, you have to override,  dispatchTouchEvent  method, and catch any IllegalArgumentExeption that can occure there.

So in your activity, (if you use fragments, then on the activity that hosts those fragments), just override this method like this

@Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        try{

            return super.dispatchTouchEvent(ev);
        }catch (IllegalArgumentException exception){
            Log.d(TAG, "dispatch key event exception");
        }
        return false;
    }

At the moment there are no visible side effects and everything looks ok, but I think that this touch event issue should be handled at library level.


#2

Hi Arkde,

Thanks for bringing this to our attention and for all the detailed information! However, I’ve actually not been able to recreate this.

Roughly how many clicks are we talking about - I mean, is it after two or three or do you have to do 10s or even 100s? No amount of clicking on both the legend and the chart would cause my sample app to crash.

As such, I wondered if you could let me know what device you were getting the crash on, what version of Android it is running and what version of ShinobiCharts for Android you are using. If you’re able to send a small sample app to info@shinobicontrols.com that reproduces this behaviour reliably I’d be very happy to try running it to see if I can get the crash.

Kind regards,

Patrick