Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: ui/android/java/src/org/chromium/ui/base/EventHandler.java

Issue 2708613002: Add EventForwarder for routing touch events (Closed)
Patch Set: base::Bind (doesn't compile yet) Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.ui.base;
6
7 import android.annotation.TargetApi;
8 import android.os.Build;
9 import android.view.MotionEvent;
10
11 import org.chromium.base.TraceEvent;
12 import org.chromium.base.annotations.CalledByNative;
13 import org.chromium.base.annotations.JNINamespace;
14
15 /**
16 * Class used to forward view, input events down to native.
17 */
18 @JNINamespace("ui")
19 public class EventHandler {
20 private long mNativeEventHandler;
21
22 // Offsets for the events that passes through.
23 private float mCurrentTouchOffsetX;
24 private float mCurrentTouchOffsetY;
25
26 @CalledByNative
27 private static EventHandler create(long nativeEventHandler) {
28 return new EventHandler(nativeEventHandler);
29 }
30
31 private EventHandler(long nativeEventHandler) {
32 mNativeEventHandler = nativeEventHandler;
33 }
34
35 @CalledByNative
36 private void destroy() {
37 mNativeEventHandler = 0;
38 }
39
40 /**
41 * @see View#onTouchEvent(MotionEvent)
42 */
43 public boolean onTouchEvent(MotionEvent event) {
44 // TODO(mustaq): Should we include MotionEvent.TOOL_TYPE_STYLUS here?
45 // crbug.com/592082
46 if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
47 // Mouse button info is incomplete on L and below
48 int apiVersion = Build.VERSION.SDK_INT;
49 if (apiVersion >= android.os.Build.VERSION_CODES.M) {
50 return onMouseEvent(event);
51 }
52 }
53
54 final boolean isTouchHandleEvent = false;
55 return sendTouchEvent(event, isTouchHandleEvent);
56 }
57
58 /**
59 * Called by PopupWindow-based touch handles.
60 * @param event the MotionEvent targeting the handle.
61 */
62 public boolean onTouchHandleEvent(MotionEvent event) {
63 final boolean isTouchHandleEvent = true;
64 return sendTouchEvent(event, isTouchHandleEvent);
65 }
66
67 private boolean sendTouchEvent(MotionEvent event, boolean isTouchHandleEvent ) {
68 assert mNativeEventHandler != 0;
69
70 TraceEvent.begin("sendTouchEvent");
71 try {
72 int eventAction = event.getActionMasked();
73
74 eventAction = SPenSupport.convertSPenEventAction(eventAction);
75
76 if (!isValidTouchEventActionForNative(eventAction)) return false;
77
78 // A zero offset is quite common, in which case the unnecessary copy should be avoided.
79 MotionEvent offset = null;
80 if (mCurrentTouchOffsetX != 0 || mCurrentTouchOffsetY != 0) {
81 offset = createOffsetMotionEvent(event);
82 event = offset;
83 }
84
85 final int pointerCount = event.getPointerCount();
86
87 float[] touchMajor = {
88 event.getTouchMajor(), pointerCount > 1 ? event.getTouchMajo r(1) : 0};
89 float[] touchMinor = {
90 event.getTouchMinor(), pointerCount > 1 ? event.getTouchMino r(1) : 0};
91
92 for (int i = 0; i < 2; i++) {
93 if (touchMajor[i] < touchMinor[i]) {
94 float tmp = touchMajor[i];
95 touchMajor[i] = touchMinor[i];
96 touchMinor[i] = tmp;
97 }
98 }
99
100 final boolean consumed = nativeOnTouchEvent(mNativeEventHandler, eve nt,
101 event.getEventTime(), eventAction, pointerCount, event.getHi storySize(),
102 event.getActionIndex(), event.getX(), event.getY(),
103 pointerCount > 1 ? event.getX(1) : 0, pointerCount > 1 ? eve nt.getY(1) : 0,
104 event.getPointerId(0), pointerCount > 1 ? event.getPointerId (1) : -1,
105 touchMajor[0], touchMajor[1], touchMinor[0], touchMinor[1],
106 event.getOrientation(), pointerCount > 1 ? event.getOrientat ion(1) : 0,
107 event.getAxisValue(MotionEvent.AXIS_TILT),
108 pointerCount > 1 ? event.getAxisValue(MotionEvent.AXIS_TILT, 1) : 0,
109 event.getRawX(), event.getRawY(), event.getToolType(0),
110 pointerCount > 1 ? event.getToolType(1) : MotionEvent.TOOL_T YPE_UNKNOWN,
111 event.getButtonState(), event.getMetaState(), isTouchHandleE vent);
112
113 if (offset != null) offset.recycle();
114 return consumed;
115 } finally {
116 TraceEvent.end("sendTouchEvent");
117 }
118 }
119
120 /**
121 * Sets the current amount to offset incoming touch events by (including Mot ionEvent and
122 * DragEvent). This is used to handle content moving and not lining up prope rly with the
123 * android input system.
124 * @param dx The X offset in pixels to shift touch events.
125 * @param dy The Y offset in pixels to shift touch events.
126 */
127 public void setCurrentTouchEventOffsets(float dx, float dy) {
128 mCurrentTouchOffsetX = dx;
129 mCurrentTouchOffsetY = dy;
130 }
131
132 private MotionEvent createOffsetMotionEvent(MotionEvent src) {
133 MotionEvent dst = MotionEvent.obtain(src);
134 dst.offsetLocation(mCurrentTouchOffsetX, mCurrentTouchOffsetY);
135 return dst;
136 }
137
138 private static boolean isValidTouchEventActionForNative(int eventAction) {
139 // Only these actions have any effect on gesture detection. Other
140 // actions have no corresponding WebTouchEvent type and may confuse the
141 // touch pipline, so we ignore them entirely.
142 return eventAction == MotionEvent.ACTION_DOWN || eventAction == MotionEv ent.ACTION_UP
143 || eventAction == MotionEvent.ACTION_CANCEL
144 || eventAction == MotionEvent.ACTION_MOVE
145 || eventAction == MotionEvent.ACTION_POINTER_DOWN
146 || eventAction == MotionEvent.ACTION_POINTER_UP;
147 }
148
149 @TargetApi(Build.VERSION_CODES.M)
150 public boolean onMouseEvent(MotionEvent event) {
151 TraceEvent.begin("sendMouseEvent");
152
153 MotionEvent offsetEvent = createOffsetMotionEvent(event);
154 try {
155 int eventAction = event.getActionMasked();
156
157 // For mousedown and mouseup events, we use ACTION_BUTTON_PRESS
158 // and ACTION_BUTTON_RELEASE respectively because they provide
159 // info about the changed-button.
160 if (eventAction == MotionEvent.ACTION_DOWN || eventAction == MotionE vent.ACTION_UP) {
161 return false;
162 }
163 sendMouseEvent(event.getEventTime(), eventAction, offsetEvent.getX() ,
164 offsetEvent.getY(), event.getPointerId(0), event.getPressure (0),
165 event.getOrientation(0), event.getAxisValue(MotionEvent.AXIS _TILT, 0),
166 event.getActionButton(), event.getButtonState(), event.getMe taState(),
167 event.getToolType(0));
168 return true;
169 } finally {
170 offsetEvent.recycle();
171 TraceEvent.end("sendMouseEvent");
172 }
173 }
174
175 @TargetApi(Build.VERSION_CODES.M)
176 public void sendMouseEvent(long timeMs, int action, float x, float y, int po interId,
177 float pressure, float orientation, float tilt, int actionButton, int buttonState,
178 int metaState, int toolType) {
179 assert mNativeEventHandler != 0;
180 nativeOnMouseEvent(mNativeEventHandler, timeMs, action, x, y, pointerId, pressure,
181 orientation, tilt, actionButton, buttonState, metaState, toolTyp e);
182 }
183
184 // All touch events (including flings, scrolls etc) accept coordinates in ph ysical pixels.
185 private native boolean nativeOnTouchEvent(long nativeEventHandler, MotionEve nt event,
186 long timeMs, int action, int pointerCount, int historySize, int acti onIndex, float x0,
187 float y0, float x1, float y1, int pointerId0, int pointerId1, float touchMajor0,
188 float touchMajor1, float touchMinor0, float touchMinor1, float orien tation0,
189 float orientation1, float tilt0, float tilt1, float rawX, float rawY ,
190 int androidToolType0, int androidToolType1, int androidButtonState,
191 int androidMetaState, boolean isTouchHandleEvent);
192 private native void nativeOnMouseEvent(long nativeEventHandler, long timeMs, int action,
193 float x, float y, int pointerId, float pressure, float orientation, float tilt,
194 int changedButton, int buttonState, int metaState, int toolType);
195 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698