W3CPointerEvents: fix NPE due to missing eventCoords (#37761)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37761

Changelog: [Android] [Fixed] - W3CPointerEvents: fix a case where cancel can cause NPE

When we need to dispatch a pointercancel event, we clear the previous state (last coordinates, last hit path) for the active pointer ID (this is needed in order to fire the proper events when the action causing the cancel is over).

Previously, we stored the previous state in the form of references to the corresponding state in the current `PointerEventState`. However, this PointerEventState is also used later when actually dispatching the events. Since the dispatch can happen asynchronously, alterations to the event state might be visible during the dispatch. In particular, we saw some cases where an NPE can occur due to removing entries from our local state (which got reflected in the event state).

This change fixes the issue by making copies of the data from the PointerEventState instead of just storing references to it.

Reviewed By: rozele

Differential Revision: D46522585

fbshipit-source-id: 78d6dd60cf8f5419870fb9f6703443c957d4d048
This commit is contained in:
Alex Danoff
2023-06-08 03:34:43 -07:00
committed by Facebook GitHub Bot
parent 10d55888cc
commit 79ae710cc5
@@ -89,8 +89,10 @@ public class JSPointerDispatcher {
private void updatePreviousStateFromEvent(MotionEvent event, PointerEventState eventState) {
// Caching the event state so we have a new "last"
mLastHitPathByPointerId = eventState.getHitPathByPointerId();
mLastEventCoordinatesByPointerId = eventState.getEventCoordinatesByPointerId();
// note: we need to make copies here as the eventState may be accessed later and we don't want
// mutations of these instance vars to affect it
mLastHitPathByPointerId = new HashMap<>(eventState.getHitPathByPointerId());
mLastEventCoordinatesByPointerId = new HashMap<>(eventState.getEventCoordinatesByPointerId());
mLastButtonState = event.getButtonState();
// Clean up any stale pointerIds