Copy MotionEvent before putting it into the queue

A MotionEvent obj can be recycled, and in that case, the native data
parts can be rewritten by a new event before the stored object is
handled in the background thread. If the new event is 'up' event, the
data in previous MotionEvent for the last pointer in 'move' event
becomes invalid.

Bug: 353928688
Test: finger up and down repeatly
Change-Id: Iaef74ab2265bb2697443ad6c97eeff2e4ee95f05
diff --git a/java/framework/src/android/system/virtualmachine/VirtualMachine.java b/java/framework/src/android/system/virtualmachine/VirtualMachine.java
index b6de9bb..1517cf0 100644
--- a/java/framework/src/android/system/virtualmachine/VirtualMachine.java
+++ b/java/framework/src/android/system/virtualmachine/VirtualMachine.java
@@ -998,7 +998,8 @@
     /** @hide */
     public boolean sendMouseEvent(MotionEvent event) {
         try {
-            mInputEventQueue.add(Pair.create(InputEventType.MOUSE, event));
+            mInputEventQueue.add(
+                    Pair.create(InputEventType.MOUSE, MotionEvent.obtainNoHistory(event)));
             return true;
         } catch (Exception e) {
             Log.e(TAG, e.toString());
@@ -1097,7 +1098,8 @@
     /** @hide */
     public boolean sendMultiTouchEvent(MotionEvent event) {
         try {
-            mInputEventQueue.add(Pair.create(InputEventType.TOUCH, event));
+            mInputEventQueue.add(
+                    Pair.create(InputEventType.TOUCH, MotionEvent.obtainNoHistory(event)));
             return true;
         } catch (Exception e) {
             Log.e(TAG, e.toString());
@@ -1194,7 +1196,8 @@
     /** @hide */
     public boolean sendTrackpadEvent(MotionEvent event) {
         try {
-            mInputEventQueue.add(Pair.create(InputEventType.TRACKPAD, event));
+            mInputEventQueue.add(
+                    Pair.create(InputEventType.TRACKPAD, MotionEvent.obtainNoHistory(event)));
             return true;
         } catch (Exception e) {
             Log.e(TAG, e.toString());
@@ -1541,6 +1544,7 @@
                                             sendMouseEventInternal(event.second);
                                             break;
                                     }
+                                    event.second.recycle();
                                 } catch (Exception e) {
                                     Log.e(TAG, e.toString());
                                 }