software-mansion / react-native-gesture-handler

Declarative API exposing platform native touch and gesture system to React Native.
https://docs.swmansion.com/react-native-gesture-handler/
MIT License
5.83k stars 952 forks source link

Android app crashes while composing different number of pointer taps in Gesture.Exclusive #2824

Closed ayonshafiul closed 1 month ago

ayonshafiul commented 1 month ago

Description

I'm trying to simulate a touchpad using this library. Everything works well but on Android while using the Gesture composer for detecting twoFingertap with minPointers(2) and other taps with minPointers(1) together inside Gesture.exclusive() the app crashes while performing two finger tap. Omitting out the twoFingerTap works ok.

Steps to reproduce

Try the following to reproduce.

import {StyleSheet, View} from 'react-native';
import {Gesture, GestureDetector} from 'react-native-gesture-handler';
import Animated from 'react-native-reanimated';

export default function TouchpadTest() {
  const twoFingerTap = Gesture.Tap()
    .maxDuration(200)
    .minPointers(2)
    .onStart(_event => {
      console.log('Two finger');
    });
  const oneFingerTap = Gesture.Tap()
    .maxDuration(200)
    .onStart((_event, success) => {
      console.log('One Finger');
    })
    .onEnd(e => {});
  const oneFingerDoubleTap = Gesture.Tap()
    .maxDuration(200)
    .numberOfTaps(2)
    .onEnd((_event, success) => {
      console.log('Double Tap');
    });

  const oneFingerTripleTap = Gesture.Tap()
    .maxDuration(200)
    .numberOfTaps(3)
    .onEnd((_event, success) => {
      console.log('Triple Tap');
    });

  const composed = Gesture.Exclusive(
    oneFingerTripleTap,
    oneFingerDoubleTap,
    oneFingerTap,
    twoFingerTap, // cuases the app to crash on two finger tap, if we omit this the app works fine
  );

  return (
    <View style={styles.container}>
      <GestureDetector gesture={composed}>
        <Animated.View style={styles.touchpad}></Animated.View>
      </GestureDetector>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'flex-start',
  },

  touchpad: {
    width: '100%',
    height: 400,
    margin: 16,
    borderRadius: 8,
    backgroundColor: '#272829',
    justifyContent: 'center',
    alignItems: 'center',
  },
});

Snack or a link to a repository

https://snack.expo.dev/nQ7zO-ybLIN4niVjiIlqP?platform=android

Gesture Handler version

2.15.0

React Native version

0.73.6

Platforms

Android, iOS

JavaScript runtime

Hermes

Workflow

React Native (without Expo)

Architecture

None

Build type

Debug mode

Device

Real device

Device model

Redmi Note 12

Acknowledgements

Yes

m-bert commented 1 month ago

Hi @ayonshafiul! I've tried to reproduce this issue on:

And I have not experienced any crash. Could you provide some more information? For example a stack trace.

ayonshafiul commented 1 month ago

Perhaps, I forgot to mention how to make the app crash. To see the crash, Run the snack from the link on an physical android device, and try tapping just one finger quite fast, then randomly switch to two fingers keep alternating very fast between one finger and two finger taps. Eventually, the app will crash at some point. If it still doesn't crash, then try alternating between two finger taps, one finger tap and pan, then two finger pan gesture (all of which you have to do very fast). Screenshot_2024-03-25-17-42-38-436_com miui bugreport

Here's a stack trace I got from expo app crash.

m-bert commented 1 month ago

Okay, I've tried following your instructions on how to reproduce this issue, but I've not been able to do this.

First of all, I've found some mistakes in your code:

  1. onStart callback doesn't have success parameter
.onStart((_event) => {
      console.log('One Finger');
    })
  1. Looking at the order of gestures in Gesture.Exclusive , twoFingerTap won't activate. It should be higher on the list:
  const composed = Gesture.Exclusive(
    twoFingerTap,
    oneFingerTripleTap,
    oneFingerDoubleTap,
    oneFingerTap,
  );

This stack trace doesn't point directly to Gesture Handler, but it can be something on our side. I'll try to look at it, but it won't be easy given that we can't reproduce this issue.

m-bert commented 1 month ago

Okay, I've just tried to reproduce it on Redmi 8T and it works fine (I've used code with suggestions that I gave earlier). Unfortunately we can't do much about this problem right now 😞

ayonshafiul commented 1 month ago

Thanks a lot for taking the time to look into this issue. If it is not resulting in a crash on other devices, I guess it could be due to the specific OS version(Xiaomi HyperOS, which is quite new atm) I am using. I will close this issue for now. I will try to test it on more devices and if I get the same crash, I will reopen this issue.

m-bert commented 1 month ago

Sounds good 👍