| OLD | NEW |
| (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 } |
| OLD | NEW |