Repository: shopify/react-native-skia
Issue: Android: Multitouch not working as expected

### Description

Multitouch example (API/Touch) is not working on Android.

### Version

0.1.139

### Steps to reproduce

Run the API/Touch Handling on Android in the Example app and perform one or more touches on the screen with multiple fingers. 

Expected: Each finger should have a colored ring that follows your finger
Observed: Only the first finger has a correct ring, all other moves and touches looks very wrong

### Snack, code example, screenshot, or link to a repository

https://github.com/Shopify/react-native-skia

Changed files:
package/android/src/main/java/com/shopify/reactnative/skia/SkiaDrawView.java

diff --git a/package/android/src/main/java/com/shopify/reactnative/skia/SkiaDrawView.java b/package/android/src/main/java/com/shopify/reactnative/skia/SkiaDrawView.java
index 4df19305..540b77e1 100644
--- a/package/android/src/main/java/com/shopify/reactnative/skia/SkiaDrawView.java
+++ b/package/android/src/main/java/com/shopify/reactnative/skia/SkiaDrawView.java
@@ -2,7 +2,6 @@ package com.shopify.reactnative.skia;
 
 import android.content.Context;
 import android.graphics.SurfaceTexture;
-import android.util.Log;
 import android.view.Surface;
 import android.view.TextureView;
 import android.view.MotionEvent;
@@ -56,37 +55,74 @@ public class SkiaDrawView extends TextureView implements TextureView.SurfaceText
 
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
-        int action = ev.getAction();
-        int count = ev.getPointerCount();
+        // https://developer.android.com/training/gestures/multi
+        int action = ev.getActionMasked();
+
         MotionEvent.PointerCoords r = new MotionEvent.PointerCoords();
-        double[] points = new double[count*5];
-        for (int i = 0; i < count; i++) {
-            ev.getPointerCoords(i, r);
-            points[i] = r.x;
-            points[i+1] = r.y;
-            points[i+2] = ev.getPressure(i);
-            switch (action) {
-                case MotionEvent.ACTION_DOWN:
-                case MotionEvent.ACTION_POINTER_DOWN:
-                    points[i+3] = 0;
-                    break;
-                case MotionEvent.ACTION_MOVE:
-                    points[i+3] = 1;
-                    break;
-                case MotionEvent.ACTION_UP:
-                case MotionEvent.ACTION_POINTER_UP:
-                    points[i+3] = 2;
-                    break;
-                case MotionEvent.ACTION_CANCEL:
-                    points[i+3] = 3;
-                    break;
+
+        double[] points;
+
+        // If this is a pointer_up/down event we need to handle it a bit specialized
+        switch (action) {
+            case MotionEvent.ACTION_POINTER_DOWN:
+            case MotionEvent.ACTION_POINTER_UP: {
+                points = new double[5];
+                int pointerIndex = ev.getActionIndex();
+                ev.getPointerCoords(pointerIndex, r);
+                points[0] = r.x;
+                points[1] = r.y;
+                points[2] = ev.getPressure(pointerIndex);
+                points[3] = motionActionToType(action);
+                points[4] = ev.getPointerId(pointerIndex);
+
+                updateTouchPoints(points);
+
+                break;
+            }
+            default: {
+                // For the rest we can just handle it like expected
+                int count = ev.getPointerCount();
+                int pointerIndex = 0;
+                points = new double[5 * count];
+                for (int i = 0; i < count; i++) {
+                    ev.getPointerCoords(i, r);
+                    points[pointerIndex++] = r.x;
+                    points[pointerIndex++] = r.y;
+                    points[pointerIndex++] = ev.getPressure(i);
+                    points[pointerIndex++] = motionActionToType(action);
+                    points[pointerIndex++] = ev.getPointerId(i);
+                }
+
+                updateTouchPoints(points);
+
+                break;
             }
-            points[i+4] = ev.getPointerId(i);
         }
-        updateTouchPoints(points);
+
         return true;
     }
 
+    private static int motionActionToType(int action) {
+        int actionType = 3;
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_POINTER_DOWN:
+                actionType = 0;
+                break;
+            case MotionEvent.ACTION_MOVE:
+                actionType = 1;
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_POINTER_UP:
+                actionType = 2;
+                break;
+            case MotionEvent.ACTION_CANCEL:
+                actionType = 3;
+                break;
+        }
+        return actionType;
+    }
+
     @Override
     public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
         mSurface = new Surface(surface);