OSDN Git Service

Fixes for touchpad capture
authorNathaniel R. Lewis <nlewis@gaikai.com>
Thu, 14 Feb 2019 01:16:17 +0000 (17:16 -0800)
committerNathaniel R. Lewis <nlewis@gaikai.com>
Tue, 19 Feb 2019 21:44:44 +0000 (13:44 -0800)
When touchpad capture is enabled, events still are received via
onGenericMotionEvent. As pointer capture sends events via
onCapturedPointerEvent, this patch changes the callback used by
captured touchpads to also be onCapturedPointerEvent.

Make events from a captured touchpad cause the device to leave touch
mode. Captured mice cause the device to exit touch mode through
the virtual dpad which is mapped to it due to being
derived from SOURCE_CLASS_TRACKBALL.

Test: Write an app that starts pointer capture on a device with a
      touchpad. Events from touchpad should be received via
      onCapturedPointerEvent.

Test: Using the captured touchpad in the first test should cause the
      view to be focusable even when not in touch mode.

Change-Id: If6fa94c66f1d9395a13fd5f31f642567256dd818

core/java/android/view/ViewRootImpl.java

index fd11ef1..8922893 100644 (file)
@@ -4817,11 +4817,8 @@ public final class ViewRootImpl implements ViewParent,
         protected int onProcess(QueuedInputEvent q) {
             if (q.mEvent instanceof KeyEvent) {
                 return processKeyEvent(q);
-            } else {
-                final int source = q.mEvent.getSource();
-                if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-                    return processPointerEvent(q);
-                }
+            } else if (q.mEvent instanceof MotionEvent) {
+                return processMotionEvent(q);
             }
             return FORWARD;
         }
@@ -4845,6 +4842,23 @@ public final class ViewRootImpl implements ViewParent,
             return FORWARD;
         }
 
+        private int processMotionEvent(QueuedInputEvent q) {
+            final MotionEvent event = (MotionEvent) q.mEvent;
+
+            if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
+                return processPointerEvent(q);
+            }
+
+            // If the motion event is from an absolute position device, exit touch mode
+            final int action = event.getActionMasked();
+            if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_SCROLL) {
+                if (event.isFromSource(InputDevice.SOURCE_CLASS_POSITION)) {
+                    ensureTouchMode(false);
+                }
+            }
+            return FORWARD;
+        }
+
         private int processPointerEvent(QueuedInputEvent q) {
             final MotionEvent event = (MotionEvent)q.mEvent;
 
@@ -5177,6 +5191,12 @@ public final class ViewRootImpl implements ViewParent,
         private int processGenericMotionEvent(QueuedInputEvent q) {
             final MotionEvent event = (MotionEvent)q.mEvent;
 
+            if (event.isFromSource(InputDevice.SOURCE_TOUCHPAD)) {
+                if (hasPointerCapture() && mView.dispatchCapturedPointerEvent(event)) {
+                    return FINISH_HANDLED;
+                }
+            }
+
             // Deliver the event to the view.
             if (mView.dispatchGenericMotionEvent(event)) {
                 return FINISH_HANDLED;