/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.view; import static android.os.IInputConstants.INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT; import static android.view.Display.DEFAULT_DISPLAY; import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Matrix; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; import android.util.Log; import android.util.SparseArray; import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; import java.lang.annotation.Retention; import java.util.Objects; /** * Object used to report movement (mouse, pen, finger, trackball) events. * Motion events may hold either absolute or relative movements and other data, * depending on the type of device. * *
* Motion events describe movements in terms of an action code and a set of axis values. * The action code specifies the state change that occurred such as a pointer going * down or up. The axis values describe the position and other movement properties. *
* For example, when the user first touches the screen, the system delivers a touch * event to the appropriate {@link View} with the action code {@link #ACTION_DOWN} * and a set of axis values that include the X and Y coordinates of the touch and * information about the pressure, size and orientation of the contact area. *
* Some devices can report multiple movement traces at the same time. Multi-touch * screens emit one movement trace for each finger. The individual fingers or * other objects that generate movement traces are referred to as pointers. * Motion events contain information about all of the pointers that are currently active * even if some of them have not moved since the last event was delivered. *
* The number of pointers only ever changes by one as individual pointers go up and down, * except when the gesture is canceled. *
* Each pointer has a unique id that is assigned when it first goes down * (indicated by {@link #ACTION_DOWN} or {@link #ACTION_POINTER_DOWN}). A pointer id * remains valid until the pointer eventually goes up (indicated by {@link #ACTION_UP} * or {@link #ACTION_POINTER_UP}) or when the gesture is canceled (indicated by * {@link #ACTION_CANCEL}). *
* The MotionEvent class provides many methods to query the position and other properties of * pointers, such as {@link #getX(int)}, {@link #getY(int)}, {@link #getAxisValue}, * {@link #getPointerId(int)}, {@link #getToolType(int)}, and many others. Most of these * methods accept the pointer index as a parameter rather than the pointer id. * The pointer index of each pointer in the event ranges from 0 to one less than the value * returned by {@link #getPointerCount()}. *
* The order in which individual pointers appear within a motion event is undefined. * Thus the pointer index of a pointer can change from one event to the next but * the pointer id of a pointer is guaranteed to remain constant as long as the pointer * remains active. Use the {@link #getPointerId(int)} method to obtain the * pointer id of a pointer to track it across all subsequent motion events in a gesture. * Then for successive motion events, use the {@link #findPointerIndex(int)} method * to obtain the pointer index for a given pointer id in that motion event. *
* Mouse and stylus buttons can be retrieved using {@link #getButtonState()}. It is a * good idea to check the button state while handling {@link #ACTION_DOWN} as part * of a touch event. The application may choose to perform some different action * if the touch event starts due to a secondary button click, such as presenting a * context menu. *
* ** For efficiency, motion events with {@link #ACTION_MOVE} may batch together * multiple movement samples within a single object. The most current * pointer coordinates are available using {@link #getX(int)} and {@link #getY(int)}. * Earlier coordinates within the batch are accessed using {@link #getHistoricalX(int, int)} * and {@link #getHistoricalY(int, int)}. The coordinates are "historical" only * insofar as they are older than the current coordinates in the batch; however, * they are still distinct from any other coordinates reported in prior motion events. * To process all coordinates in the batch in time order, first consume the historical * coordinates then consume the current coordinates. *
* Example: Consuming all samples for all pointers in a motion event in time order. *
* void printSamples(MotionEvent ev) {
* final int historySize = ev.getHistorySize();
* final int pointerCount = ev.getPointerCount();
* for (int h = 0; h < historySize; h++) {
* System.out.printf("At time %d:", ev.getHistoricalEventTime(h));
* for (int p = 0; p < pointerCount; p++) {
* System.out.printf(" pointer %d: (%f,%f)",
* ev.getPointerId(p), ev.getHistoricalX(p, h), ev.getHistoricalY(p, h));
* }
* }
* System.out.printf("At time %d:", ev.getEventTime());
* for (int p = 0; p < pointerCount; p++) {
* System.out.printf(" pointer %d: (%f,%f)",
* ev.getPointerId(p), ev.getX(p), ev.getY(p));
* }
* }
*
*
* * The interpretation of the contents of a MotionEvent varies significantly depending * on the source class of the device. *
* On pointing devices with source class {@link InputDevice#SOURCE_CLASS_POINTER} * such as touch screens, the pointer coordinates specify absolute * positions such as view X/Y coordinates. Each complete gesture is represented * by a sequence of motion events with actions that describe pointer state transitions * and movements. A gesture starts with a motion event with {@link #ACTION_DOWN} * that provides the location of the first pointer down. As each additional * pointer that goes down or up, the framework will generate a motion event with * {@link #ACTION_POINTER_DOWN} or {@link #ACTION_POINTER_UP} accordingly. * Pointer movements are described by motion events with {@link #ACTION_MOVE}. * Finally, a gesture end either when the final pointer goes up as represented * by a motion event with {@link #ACTION_UP} or when gesture is canceled * with {@link #ACTION_CANCEL}. *
* Some pointing devices such as mice may support vertical and/or horizontal scrolling. * A scroll event is reported as a generic motion event with {@link #ACTION_SCROLL} that * includes the relative scroll offset in the {@link #AXIS_VSCROLL} and * {@link #AXIS_HSCROLL} axes. See {@link #getAxisValue(int)} for information * about retrieving these additional axes. *
* On trackball devices with source class {@link InputDevice#SOURCE_CLASS_TRACKBALL}, * the pointer coordinates specify relative movements as X/Y deltas. * A trackball gesture consists of a sequence of movements described by motion * events with {@link #ACTION_MOVE} interspersed with occasional {@link #ACTION_DOWN} * or {@link #ACTION_UP} motion events when the trackball button is pressed or released. *
* On joystick devices with source class {@link InputDevice#SOURCE_CLASS_JOYSTICK}, * the pointer coordinates specify the absolute position of the joystick axes. * The joystick axis values are normalized to a range of -1.0 to 1.0 where 0.0 corresponds * to the center position. More information about the set of available axes and the * range of motion can be obtained using {@link InputDevice#getMotionRange}. * Some common joystick axes are {@link #AXIS_X}, {@link #AXIS_Y}, * {@link #AXIS_HAT_X}, {@link #AXIS_HAT_Y}, {@link #AXIS_Z} and {@link #AXIS_RZ}. *
* Refer to {@link InputDevice} for more information about how different kinds of * input devices and sources represent pointer coordinates. *
* ** Motion events are always delivered to views as a consistent stream of events. * What constitutes a consistent stream varies depending on the type of device. * For touch events, consistency implies that pointers go down one at a time, * move around as a group and then go up one at a time or are canceled. *
* While the framework tries to deliver consistent streams of motion events to * views, it cannot guarantee it. Some events may be dropped or modified by * containing views in the application before they are delivered thereby making * the stream of events inconsistent. Views should always be prepared to * handle {@link #ACTION_CANCEL} and should tolerate anomalous * situations such as receiving a new {@link #ACTION_DOWN} without first having * received an {@link #ACTION_UP} for the prior gesture. *
*/ public final class MotionEvent extends InputEvent implements Parcelable { private static final String TAG = "MotionEvent"; private static final long NS_PER_MS = 1000000; private static final String LABEL_PREFIX = "AXIS_"; private static final boolean DEBUG_CONCISE_TOSTRING = false; /** * An invalid pointer id. * * This value (-1) can be used as a placeholder to indicate that a pointer id * has not been assigned or is not available. It cannot appear as * a pointer id inside a {@link MotionEvent}. */ public static final int INVALID_POINTER_ID = -1; /** * Bit mask of the parts of the action code that are the action itself. */ public static final int ACTION_MASK = 0xff; /** * Constant for {@link #getActionMasked}: A pressed gesture has started, the * motion contains the initial starting location. ** This is also a good time to check the button state to distinguish * secondary and tertiary button clicks and handle them appropriately. * Use {@link #getButtonState} to retrieve the button state. *
*/ public static final int ACTION_DOWN = 0; /** * Constant for {@link #getActionMasked}: A pressed gesture has finished, the * motion contains the final release location as well as any intermediate * points since the last down or move event. */ public static final int ACTION_UP = 1; /** * Constant for {@link #getActionMasked}: A change has happened during a * press gesture (between {@link #ACTION_DOWN} and {@link #ACTION_UP}). * The motion contains the most recent point, as well as any intermediate * points since the last down or move event. */ public static final int ACTION_MOVE = 2; /** * Constant for {@link #getActionMasked}: The current gesture has been aborted. * You will not receive any more points in it. You should treat this as * an up event, but not perform any action that you normally would. */ public static final int ACTION_CANCEL = 3; /** * Constant for {@link #getActionMasked}: A movement has happened outside of the * normal bounds of the UI element. This does not provide a full gesture, * but only the initial location of the movement/touch. ** Note: Because the location of any event will be outside the * bounds of the view hierarchy, it will not get dispatched to * any children of a ViewGroup by default. Therefore, * movements with ACTION_OUTSIDE should be handled in either the * root {@link View} or in the appropriate {@link Window.Callback} * (e.g. {@link android.app.Activity} or {@link android.app.Dialog}). *
*/ public static final int ACTION_OUTSIDE = 4; /** * Constant for {@link #getActionMasked}: A non-primary pointer has gone down. ** Use {@link #getActionIndex} to retrieve the index of the pointer that changed. *
* The index is encoded in the {@link #ACTION_POINTER_INDEX_MASK} bits of the * unmasked action returned by {@link #getAction}. *
*/ public static final int ACTION_POINTER_DOWN = 5; /** * Constant for {@link #getActionMasked}: A non-primary pointer has gone up. ** Use {@link #getActionIndex} to retrieve the index of the pointer that changed. *
* The index is encoded in the {@link #ACTION_POINTER_INDEX_MASK} bits of the * unmasked action returned by {@link #getAction}. *
*/ public static final int ACTION_POINTER_UP = 6; /** * Constant for {@link #getActionMasked}: A change happened but the pointer * is not down (unlike {@link #ACTION_MOVE}). The motion contains the most * recent point, as well as any intermediate points since the last * hover move event. ** This action is always delivered to the window or view under the pointer. *
* This action is not a touch event so it is delivered to * {@link View#onGenericMotionEvent(MotionEvent)} rather than * {@link View#onTouchEvent(MotionEvent)}. *
*/ public static final int ACTION_HOVER_MOVE = 7; /** * Constant for {@link #getActionMasked}: The motion event contains relative * vertical and/or horizontal scroll offsets. Use {@link #getAxisValue(int)} * to retrieve the information from {@link #AXIS_VSCROLL} and {@link #AXIS_HSCROLL}. * The pointer may or may not be down when this event is dispatched. ** This action is always delivered to the window or view under the pointer, which * may not be the window or view currently touched. *
* This action is not a touch event so it is delivered to * {@link View#onGenericMotionEvent(MotionEvent)} rather than * {@link View#onTouchEvent(MotionEvent)}. *
*/ public static final int ACTION_SCROLL = 8; /** * Constant for {@link #getActionMasked}: The pointer is not down but has entered the * boundaries of a window or view. ** This action is always delivered to the window or view under the pointer. *
* This action is not a touch event so it is delivered to * {@link View#onGenericMotionEvent(MotionEvent)} rather than * {@link View#onTouchEvent(MotionEvent)}. *
*/ public static final int ACTION_HOVER_ENTER = 9; /** * Constant for {@link #getActionMasked}: The pointer is not down but has exited the * boundaries of a window or view. ** This action is always delivered to the window or view that was previously under the pointer. *
* This action is not a touch event so it is delivered to * {@link View#onGenericMotionEvent(MotionEvent)} rather than * {@link View#onTouchEvent(MotionEvent)}. *
*/ public static final int ACTION_HOVER_EXIT = 10; /** * Constant for {@link #getActionMasked}: A button has been pressed. * ** Use {@link #getActionButton()} to get which button was pressed. *
* This action is not a touch event so it is delivered to * {@link View#onGenericMotionEvent(MotionEvent)} rather than * {@link View#onTouchEvent(MotionEvent)}. *
*/ public static final int ACTION_BUTTON_PRESS = 11; /** * Constant for {@link #getActionMasked}: A button has been released. * ** Use {@link #getActionButton()} to get which button was released. *
* This action is not a touch event so it is delivered to * {@link View#onGenericMotionEvent(MotionEvent)} rather than * {@link View#onTouchEvent(MotionEvent)}. *
*/ public static final int ACTION_BUTTON_RELEASE = 12; /** * Bits in the action code that represent a pointer index, used with * {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}. Shifting * down by {@link #ACTION_POINTER_INDEX_SHIFT} provides the actual pointer * index where the data for the pointer going up or down can be found; you can * get its identifier with {@link #getPointerId(int)} and the actual * data with {@link #getX(int)} etc. * * @see #getActionIndex */ public static final int ACTION_POINTER_INDEX_MASK = 0xff00; /** * Bit shift for the action bits holding the pointer index as * defined by {@link #ACTION_POINTER_INDEX_MASK}. * * @see #getActionIndex */ public static final int ACTION_POINTER_INDEX_SHIFT = 8; /** * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the * data index associated with {@link #ACTION_POINTER_DOWN}. */ @Deprecated public static final int ACTION_POINTER_1_DOWN = ACTION_POINTER_DOWN | 0x0000; /** * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the * data index associated with {@link #ACTION_POINTER_DOWN}. */ @Deprecated public static final int ACTION_POINTER_2_DOWN = ACTION_POINTER_DOWN | 0x0100; /** * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the * data index associated with {@link #ACTION_POINTER_DOWN}. */ @Deprecated public static final int ACTION_POINTER_3_DOWN = ACTION_POINTER_DOWN | 0x0200; /** * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the * data index associated with {@link #ACTION_POINTER_UP}. */ @Deprecated public static final int ACTION_POINTER_1_UP = ACTION_POINTER_UP | 0x0000; /** * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the * data index associated with {@link #ACTION_POINTER_UP}. */ @Deprecated public static final int ACTION_POINTER_2_UP = ACTION_POINTER_UP | 0x0100; /** * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the * data index associated with {@link #ACTION_POINTER_UP}. */ @Deprecated public static final int ACTION_POINTER_3_UP = ACTION_POINTER_UP | 0x0200; /** * @deprecated Renamed to {@link #ACTION_POINTER_INDEX_MASK} to match * the actual data contained in these bits. */ @Deprecated public static final int ACTION_POINTER_ID_MASK = 0xff00; /** * @deprecated Renamed to {@link #ACTION_POINTER_INDEX_SHIFT} to match * the actual data contained in these bits. */ @Deprecated public static final int ACTION_POINTER_ID_SHIFT = 8; /** * This flag indicates that the window that received this motion event is partly * or wholly obscured by another visible window above it. This flag is set to true * if the event directly passed through the obscured area. * * A security sensitive application can check this flag to identify situations in which * a malicious application may have covered up part of its content for the purpose * of misleading the user or hijacking touches. An appropriate response might be * to drop the suspect touches or to take additional precautions to confirm the user's * actual intent. */ public static final int FLAG_WINDOW_IS_OBSCURED = 0x1; /** * This flag indicates that the window that received this motion event is partly * or wholly obscured by another visible window above it. This flag is set to true * even if the event did not directly pass through the obscured area. * * A security sensitive application can check this flag to identify situations in which * a malicious application may have covered up part of its content for the purpose * of misleading the user or hijacking touches. An appropriate response might be * to drop the suspect touches or to take additional precautions to confirm the user's * actual intent. * * Unlike FLAG_WINDOW_IS_OBSCURED, this is true even if the window that received this event is * obstructed in areas other than the touched location. */ public static final int FLAG_WINDOW_IS_PARTIALLY_OBSCURED = 0x2; /** * This private flag is only set on {@link #ACTION_HOVER_MOVE} events and indicates that * this event will be immediately followed by a {@link #ACTION_HOVER_EXIT}. It is used to * prevent generating redundant {@link #ACTION_HOVER_ENTER} events. * @hide */ public static final int FLAG_HOVER_EXIT_PENDING = 0x4; /** * This flag indicates that the event has been generated by a gesture generator. It * provides a hint to the GestureDetector to not apply any touch slop. * * @hide */ public static final int FLAG_IS_GENERATED_GESTURE = 0x8; /** * This flag associated with {@link #ACTION_POINTER_UP}, this indicates that the pointer * has been canceled. Typically this is used for palm event when the user has accidental * touches. * @hide */ public static final int FLAG_CANCELED = 0x20; /** * This flag indicates that the event will not cause a focus change if it is directed to an * unfocused window, even if it an {@link #ACTION_DOWN}. This is typically used with pointer * gestures to allow the user to direct gestures to an unfocused window without bringing the * window into focus. * @hide */ public static final int FLAG_NO_FOCUS_CHANGE = 0x40; /** * This flag indicates that this event was modified by or generated from an accessibility * service. Value = 0x800 * @hide */ @TestApi public static final int FLAG_IS_ACCESSIBILITY_EVENT = INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT; /** * Private flag that indicates when the system has detected that this motion event * may be inconsistent with respect to the sequence of previously delivered motion events, * such as when a pointer move event is sent but the pointer is not down. * * @hide * @see #isTainted * @see #setTainted */ public static final int FLAG_TAINTED = 0x80000000; /** * Private flag indicating that this event was synthesized by the system and should be delivered * to the accessibility focused view first. When being dispatched such an event is not handled * by predecessors of the accessibility focused view and after the event reaches that view the * flag is cleared and normal event dispatch is performed. This ensures that the platform can * click on any view that has accessibility focus which is semantically equivalent to asking the * view to perform a click accessibility action but more generic as views not implementing click * action correctly can still be activated. * * @hide * @see #isTargetAccessibilityFocus() * @see #setTargetAccessibilityFocus(boolean) */ public static final int FLAG_TARGET_ACCESSIBILITY_FOCUS = 0x40000000; /** * Flag indicating the motion event intersected the top edge of the screen. */ public static final int EDGE_TOP = 0x00000001; /** * Flag indicating the motion event intersected the bottom edge of the screen. */ public static final int EDGE_BOTTOM = 0x00000002; /** * Flag indicating the motion event intersected the left edge of the screen. */ public static final int EDGE_LEFT = 0x00000004; /** * Flag indicating the motion event intersected the right edge of the screen. */ public static final int EDGE_RIGHT = 0x00000008; /** * Axis constant: X axis of a motion event. **
*
*
*
*
*
* When the touch is circular, the major and minor axis lengths will be equal to one another. *
* * @see #getTouchMinor(int) * @see #getHistoricalTouchMinor(int, int) * @see MotionEvent.PointerCoords#touchMinor * @see InputDevice#getMotionRange */ public static final int AXIS_TOUCH_MINOR = 5; /** * Axis constant: ToolMajor axis of a motion event. **
* When the touch is circular, the major and minor axis lengths will be equal to one another. *
* The tool size may be larger than the touch size since the tool may not be fully * in contact with the touch sensor. *
* * @see #getToolMajor(int) * @see #getHistoricalToolMajor(int, int) * @see MotionEvent.PointerCoords#toolMajor * @see InputDevice#getMotionRange */ public static final int AXIS_TOOL_MAJOR = 6; /** * Axis constant: ToolMinor axis of a motion event. **
* When the touch is circular, the major and minor axis lengths will be equal to one another. *
* The tool size may be larger than the touch size since the tool may not be fully * in contact with the touch sensor. *
* * @see #getToolMinor(int) * @see #getHistoricalToolMinor(int, int) * @see MotionEvent.PointerCoords#toolMinor * @see InputDevice#getMotionRange */ public static final int AXIS_TOOL_MINOR = 7; /** * Axis constant: Orientation axis of a motion event. **
*
* This axis should be used to scroll views vertically. *
* * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_VSCROLL = 9; /** * Axis constant: Horizontal Scroll axis of a motion event. **
* This axis should be used to scroll views horizontally. *
* * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_HSCROLL = 10; /** * Axis constant: Z axis of a motion event. **
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* This axis should be used for scroll events that are neither strictly vertical nor horizontal. * A good example would be the rotation of a rotary encoder input device. *
* * @see #getAxisValue(int, int) */ public static final int AXIS_SCROLL = 26; /** * Axis constant: The movement of x position of a motion event. **
* This is similar to {@link #AXIS_RELATIVE_X} but for y-axis. *
* * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int, int) * @see InputDevice#getMotionRange */ public static final int AXIS_RELATIVE_Y = 28; /** * Axis constant: Generic 1 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_1 = 32; /** * Axis constant: Generic 2 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_2 = 33; /** * Axis constant: Generic 3 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_3 = 34; /** * Axis constant: Generic 4 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_4 = 35; /** * Axis constant: Generic 5 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_5 = 36; /** * Axis constant: Generic 6 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_6 = 37; /** * Axis constant: Generic 7 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_7 = 38; /** * Axis constant: Generic 8 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_8 = 39; /** * Axis constant: Generic 9 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_9 = 40; /** * Axis constant: Generic 10 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_10 = 41; /** * Axis constant: Generic 11 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_11 = 42; /** * Axis constant: Generic 12 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_12 = 43; /** * Axis constant: Generic 13 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_13 = 44; /** * Axis constant: Generic 14 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_14 = 45; /** * Axis constant: Generic 15 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_15 = 46; /** * Axis constant: Generic 16 axis of a motion event. * The interpretation of a generic axis is device-specific. * * @see #getAxisValue(int, int) * @see #getHistoricalAxisValue(int, int, int) * @see MotionEvent.PointerCoords#getAxisValue(int) * @see InputDevice#getMotionRange */ public static final int AXIS_GENERIC_16 = 47; // NOTE: If you add a new axis here you must also add it to: // native/include/android/input.h // frameworks/base/include/ui/KeycodeLabels.h // Symbolic names of all axes. private static final SparseArray* The system may send a {@link KeyEvent#KEYCODE_BACK} key press to the application * when this button is pressed. *
* * @see #getButtonState */ public static final int BUTTON_BACK = 1 << 3; /** * Button constant: Forward button pressed (mouse forward button). ** The system may send a {@link KeyEvent#KEYCODE_FORWARD} key press to the application * when this button is pressed. *
* * @see #getButtonState */ public static final int BUTTON_FORWARD = 1 << 4; /** * Button constant: Primary stylus button pressed. * * @see #getButtonState */ public static final int BUTTON_STYLUS_PRIMARY = 1 << 5; /** * Button constant: Secondary stylus button pressed. * * @see #getButtonState */ public static final int BUTTON_STYLUS_SECONDARY = 1 << 6; // NOTE: If you add a new axis here you must also add it to: // native/include/android/input.h // Symbolic names of all button states in bit order from least significant // to most significant. private static final String[] BUTTON_SYMBOLIC_NAMES = new String[] { "BUTTON_PRIMARY", "BUTTON_SECONDARY", "BUTTON_TERTIARY", "BUTTON_BACK", "BUTTON_FORWARD", "BUTTON_STYLUS_PRIMARY", "BUTTON_STYLUS_SECONDARY", "0x00000080", "0x00000100", "0x00000200", "0x00000400", "0x00000800", "0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", "0x00020000", "0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", "0x00800000", "0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", "0x20000000", "0x40000000", "0x80000000", }; /** * Classification constant: None. * * No additional information is available about the current motion event stream. * * @see #getClassification */ public static final int CLASSIFICATION_NONE = 0; /** * Classification constant: Ambiguous gesture. * * The user's intent with respect to the current event stream is not yet determined. * Gestural actions, such as scrolling, should be inhibited until the classification resolves * to another value or the event stream ends. * * @see #getClassification */ public static final int CLASSIFICATION_AMBIGUOUS_GESTURE = 1; /** * Classification constant: Deep press. * * The current event stream represents the user intentionally pressing harder on the screen. * This classification type should be used to accelerate the long press behaviour. * * @see #getClassification */ public static final int CLASSIFICATION_DEEP_PRESS = 2; /** @hide */ @Retention(SOURCE) @IntDef(prefix = { "CLASSIFICATION" }, value = { CLASSIFICATION_NONE, CLASSIFICATION_AMBIGUOUS_GESTURE, CLASSIFICATION_DEEP_PRESS}) public @interface Classification {}; /** * Tool type constant: Unknown tool type. * This constant is used when the tool type is not known or is not relevant, * such as for a trackball or other non-pointing device. * * @see #getToolType */ public static final int TOOL_TYPE_UNKNOWN = 0; /** * Tool type constant: The tool is a finger. * * @see #getToolType */ public static final int TOOL_TYPE_FINGER = 1; /** * Tool type constant: The tool is a stylus. * * @see #getToolType */ public static final int TOOL_TYPE_STYLUS = 2; /** * Tool type constant: The tool is a mouse. * * @see #getToolType */ public static final int TOOL_TYPE_MOUSE = 3; /** * Tool type constant: The tool is an eraser or a stylus being used in an inverted posture. * * @see #getToolType */ public static final int TOOL_TYPE_ERASER = 4; // NOTE: If you add a new tool type here you must also add it to: // native/include/android/input.h // Symbolic names of all tool types. private static final SparseArray* Specifically excludes pointer events with action {@link #ACTION_HOVER_MOVE}, * {@link #ACTION_HOVER_ENTER}, {@link #ACTION_HOVER_EXIT}, or {@link #ACTION_SCROLL} * because they are not actually touch events (the pointer is not down). *
* @return True if this motion event is a touch event. * @hide */ public final boolean isTouchEvent() { return nativeIsTouchEvent(mNativePtr); } /** * Gets the motion event flags. * * @see #FLAG_WINDOW_IS_OBSCURED */ public final int getFlags() { return nativeGetFlags(mNativePtr); } /** @hide */ @Override public final boolean isTainted() { final int flags = getFlags(); return (flags & FLAG_TAINTED) != 0; } /** @hide */ @Override public final void setTainted(boolean tainted) { final int flags = getFlags(); nativeSetFlags(mNativePtr, tainted ? flags | FLAG_TAINTED : flags & ~FLAG_TAINTED); } /** @hide */ public boolean isTargetAccessibilityFocus() { final int flags = getFlags(); return (flags & FLAG_TARGET_ACCESSIBILITY_FOCUS) != 0; } /** @hide */ public void setTargetAccessibilityFocus(boolean targetsFocus) { final int flags = getFlags(); nativeSetFlags(mNativePtr, targetsFocus ? flags | FLAG_TARGET_ACCESSIBILITY_FOCUS : flags & ~FLAG_TARGET_ACCESSIBILITY_FOCUS); } /** @hide */ public final boolean isHoverExitPending() { final int flags = getFlags(); return (flags & FLAG_HOVER_EXIT_PENDING) != 0; } /** @hide */ public void setHoverExitPending(boolean hoverExitPending) { final int flags = getFlags(); nativeSetFlags(mNativePtr, hoverExitPending ? flags | FLAG_HOVER_EXIT_PENDING : flags & ~FLAG_HOVER_EXIT_PENDING); } /** * Returns the time (in ms) when the user originally pressed down to start * a stream of position events. */ public final long getDownTime() { return nativeGetDownTimeNanos(mNativePtr) / NS_PER_MS; } /** * Sets the time (in ms) when the user originally pressed down to start * a stream of position events. * * @hide */ @UnsupportedAppUsage public final void setDownTime(long downTime) { nativeSetDownTimeNanos(mNativePtr, downTime * NS_PER_MS); } /** * Retrieve the time this event occurred, * in the {@link android.os.SystemClock#uptimeMillis} time base. * * @return Returns the time this event occurred, * in the {@link android.os.SystemClock#uptimeMillis} time base. */ @Override public final long getEventTime() { return nativeGetEventTimeNanos(mNativePtr, HISTORY_CURRENT) / NS_PER_MS; } /** * Retrieve the time this event occurred, * in the {@link android.os.SystemClock#uptimeMillis} time base but with * nanosecond precision. ** The value is in nanosecond precision but it may not have nanosecond accuracy. *
* * @return Returns the time this event occurred, * in the {@link android.os.SystemClock#uptimeMillis} time base but with * nanosecond precision. * * @hide */ @Override @UnsupportedAppUsage public final long getEventTimeNano() { return nativeGetEventTimeNanos(mNativePtr, HISTORY_CURRENT); } /** * {@link #getX(int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @see #AXIS_X */ public final float getX() { return nativeGetAxisValue(mNativePtr, AXIS_X, 0, HISTORY_CURRENT); } /** * {@link #getY(int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @see #AXIS_Y */ public final float getY() { return nativeGetAxisValue(mNativePtr, AXIS_Y, 0, HISTORY_CURRENT); } /** * {@link #getPressure(int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @see #AXIS_PRESSURE */ public final float getPressure() { return nativeGetAxisValue(mNativePtr, AXIS_PRESSURE, 0, HISTORY_CURRENT); } /** * {@link #getSize(int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @see #AXIS_SIZE */ public final float getSize() { return nativeGetAxisValue(mNativePtr, AXIS_SIZE, 0, HISTORY_CURRENT); } /** * {@link #getTouchMajor(int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @see #AXIS_TOUCH_MAJOR */ public final float getTouchMajor() { return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MAJOR, 0, HISTORY_CURRENT); } /** * {@link #getTouchMinor(int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @see #AXIS_TOUCH_MINOR */ public final float getTouchMinor() { return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MINOR, 0, HISTORY_CURRENT); } /** * {@link #getToolMajor(int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @see #AXIS_TOOL_MAJOR */ public final float getToolMajor() { return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MAJOR, 0, HISTORY_CURRENT); } /** * {@link #getToolMinor(int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @see #AXIS_TOOL_MINOR */ public final float getToolMinor() { return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MINOR, 0, HISTORY_CURRENT); } /** * {@link #getOrientation(int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @see #AXIS_ORIENTATION */ public final float getOrientation() { return nativeGetAxisValue(mNativePtr, AXIS_ORIENTATION, 0, HISTORY_CURRENT); } /** * {@link #getAxisValue(int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @param axis The axis identifier for the axis value to retrieve. * * @see #AXIS_X * @see #AXIS_Y */ public final float getAxisValue(int axis) { return nativeGetAxisValue(mNativePtr, axis, 0, HISTORY_CURRENT); } /** * The number of pointers of data contained in this event. Always * >= 1. */ public final int getPointerCount() { return nativeGetPointerCount(mNativePtr); } /** * Return the pointer identifier associated with a particular pointer * data index in this event. The identifier tells you the actual pointer * number associated with the data, accounting for individual pointers * going up and down since the start of the current gesture. * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. */ public final int getPointerId(int pointerIndex) { return nativeGetPointerId(mNativePtr, pointerIndex); } /** * Gets the tool type of a pointer for the given pointer index. * The tool type indicates the type of tool used to make contact such * as a finger or stylus, if known. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @return The tool type of the pointer. * * @see #TOOL_TYPE_UNKNOWN * @see #TOOL_TYPE_FINGER * @see #TOOL_TYPE_STYLUS * @see #TOOL_TYPE_MOUSE */ public final int getToolType(int pointerIndex) { return nativeGetToolType(mNativePtr, pointerIndex); } /** * Given a pointer identifier, find the index of its data in the event. * * @param pointerId The identifier of the pointer to be found. * @return Returns either the index of the pointer (for use with * {@link #getX(int)} et al.), or -1 if there is no data available for * that pointer identifier. */ public final int findPointerIndex(int pointerId) { return nativeFindPointerIndex(mNativePtr, pointerId); } /** * Returns the X coordinate of this event for the given pointer * index (use {@link #getPointerId(int)} to find the pointer * identifier for this index). * Whole numbers are pixels; the * value may have a fraction for input devices that are sub-pixel precise. * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * * @see #AXIS_X */ public final float getX(int pointerIndex) { return nativeGetAxisValue(mNativePtr, AXIS_X, pointerIndex, HISTORY_CURRENT); } /** * Returns the Y coordinate of this event for the given pointer * index (use {@link #getPointerId(int)} to find the pointer * identifier for this index). * Whole numbers are pixels; the * value may have a fraction for input devices that are sub-pixel precise. * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * * @see #AXIS_Y */ public final float getY(int pointerIndex) { return nativeGetAxisValue(mNativePtr, AXIS_Y, pointerIndex, HISTORY_CURRENT); } /** * Returns the current pressure of this event for the given pointer * index (use {@link #getPointerId(int)} to find the pointer * identifier for this index). * The pressure generally * ranges from 0 (no pressure at all) to 1 (normal pressure), however * values higher than 1 may be generated depending on the calibration of * the input device. * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * * @see #AXIS_PRESSURE */ public final float getPressure(int pointerIndex) { return nativeGetAxisValue(mNativePtr, AXIS_PRESSURE, pointerIndex, HISTORY_CURRENT); } /** * Returns a scaled value of the approximate size for the given pointer * index (use {@link #getPointerId(int)} to find the pointer * identifier for this index). * This represents some approximation of the area of the screen being * pressed; the actual value in pixels corresponding to the * touch is normalized with the device specific range of values * and scaled to a value between 0 and 1. The value of size can be used to * determine fat touch events. * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * * @see #AXIS_SIZE */ public final float getSize(int pointerIndex) { return nativeGetAxisValue(mNativePtr, AXIS_SIZE, pointerIndex, HISTORY_CURRENT); } /** * Returns the length of the major axis of an ellipse that describes the touch * area at the point of contact for the given pointer * index (use {@link #getPointerId(int)} to find the pointer * identifier for this index). * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * * @see #AXIS_TOUCH_MAJOR */ public final float getTouchMajor(int pointerIndex) { return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MAJOR, pointerIndex, HISTORY_CURRENT); } /** * Returns the length of the minor axis of an ellipse that describes the touch * area at the point of contact for the given pointer * index (use {@link #getPointerId(int)} to find the pointer * identifier for this index). * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * * @see #AXIS_TOUCH_MINOR */ public final float getTouchMinor(int pointerIndex) { return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MINOR, pointerIndex, HISTORY_CURRENT); } /** * Returns the length of the major axis of an ellipse that describes the size of * the approaching tool for the given pointer * index (use {@link #getPointerId(int)} to find the pointer * identifier for this index). * The tool area represents the estimated size of the finger or pen that is * touching the device independent of its actual touch area at the point of contact. * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * * @see #AXIS_TOOL_MAJOR */ public final float getToolMajor(int pointerIndex) { return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MAJOR, pointerIndex, HISTORY_CURRENT); } /** * Returns the length of the minor axis of an ellipse that describes the size of * the approaching tool for the given pointer * index (use {@link #getPointerId(int)} to find the pointer * identifier for this index). * The tool area represents the estimated size of the finger or pen that is * touching the device independent of its actual touch area at the point of contact. * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * * @see #AXIS_TOOL_MINOR */ public final float getToolMinor(int pointerIndex) { return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MINOR, pointerIndex, HISTORY_CURRENT); } /** * Returns the orientation of the touch area and tool area in radians clockwise from vertical * for the given pointer index (use {@link #getPointerId(int)} to find the pointer * identifier for this index). * An angle of 0 radians indicates that the major axis of contact is oriented * upwards, is perfectly circular or is of unknown orientation. A positive angle * indicates that the major axis of contact is oriented to the right. A negative angle * indicates that the major axis of contact is oriented to the left. * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians * (finger pointing fully right). * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * * @see #AXIS_ORIENTATION */ public final float getOrientation(int pointerIndex) { return nativeGetAxisValue(mNativePtr, AXIS_ORIENTATION, pointerIndex, HISTORY_CURRENT); } /** * Returns the value of the requested axis for the given pointer index * (use {@link #getPointerId(int)} to find the pointer identifier for this index). * * @param axis The axis identifier for the axis value to retrieve. * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @return The value of the axis, or 0 if the axis is not available. * * @see #AXIS_X * @see #AXIS_Y */ public final float getAxisValue(int axis, int pointerIndex) { return nativeGetAxisValue(mNativePtr, axis, pointerIndex, HISTORY_CURRENT); } /** * Populates a {@link PointerCoords} object with pointer coordinate data for * the specified pointer index. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @param outPointerCoords The pointer coordinate object to populate. * * @see PointerCoords */ public final void getPointerCoords(int pointerIndex, PointerCoords outPointerCoords) { nativeGetPointerCoords(mNativePtr, pointerIndex, HISTORY_CURRENT, outPointerCoords); } /** * Populates a {@link PointerProperties} object with pointer properties for * the specified pointer index. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @param outPointerProperties The pointer properties object to populate. * * @see PointerProperties */ public final void getPointerProperties(int pointerIndex, PointerProperties outPointerProperties) { nativeGetPointerProperties(mNativePtr, pointerIndex, outPointerProperties); } /** * Returns the state of any meta / modifier keys that were in effect when * the event was generated. This is the same values as those * returned by {@link KeyEvent#getMetaState() KeyEvent.getMetaState}. * * @return an integer in which each bit set to 1 represents a pressed * meta key * * @see KeyEvent#getMetaState() */ public final int getMetaState() { return nativeGetMetaState(mNativePtr); } /** * Gets the state of all buttons that are pressed such as a mouse or stylus button. * * @return The button state. * * @see #BUTTON_PRIMARY * @see #BUTTON_SECONDARY * @see #BUTTON_TERTIARY * @see #BUTTON_FORWARD * @see #BUTTON_BACK * @see #BUTTON_STYLUS_PRIMARY * @see #BUTTON_STYLUS_SECONDARY */ public final int getButtonState() { return nativeGetButtonState(mNativePtr); } /** * Sets the bitfield indicating which buttons are pressed. * * @see #getButtonState() * @hide */ @TestApi public final void setButtonState(int buttonState) { nativeSetButtonState(mNativePtr, buttonState); } /** * Returns the classification for the current gesture. * The classification may change as more events become available for the same gesture. * * @see #CLASSIFICATION_NONE * @see #CLASSIFICATION_AMBIGUOUS_GESTURE * @see #CLASSIFICATION_DEEP_PRESS */ public @Classification int getClassification() { return nativeGetClassification(mNativePtr); } /** * Gets which button has been modified during a press or release action. * * For actions other than {@link #ACTION_BUTTON_PRESS} and {@link #ACTION_BUTTON_RELEASE} * the returned value is undefined. * * @see #getButtonState() */ public final int getActionButton() { return nativeGetActionButton(mNativePtr); } /** * Sets the action button for the event. * * @see #getActionButton() * @hide */ @UnsupportedAppUsage @TestApi public final void setActionButton(int button) { nativeSetActionButton(mNativePtr, button); } /** * Returns the original raw X coordinate of this event. For touch * events on the screen, this is the original location of the event * on the screen, before it had been adjusted for the containing window * and views. * * @see #getX(int) * @see #AXIS_X */ public final float getRawX() { return nativeGetRawAxisValue(mNativePtr, AXIS_X, 0, HISTORY_CURRENT); } /** * Returns the original raw Y coordinate of this event. For touch * events on the screen, this is the original location of the event * on the screen, before it had been adjusted for the containing window * and views. * * @see #getY(int) * @see #AXIS_Y */ public final float getRawY() { return nativeGetRawAxisValue(mNativePtr, AXIS_Y, 0, HISTORY_CURRENT); } /** * Returns the original raw X coordinate of this event. For touch * events on the screen, this is the original location of the event * on the screen, before it had been adjusted for the containing window * and views. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * * @see #getX(int) * @see #AXIS_X */ public float getRawX(int pointerIndex) { return nativeGetRawAxisValue(mNativePtr, AXIS_X, pointerIndex, HISTORY_CURRENT); } /** * Returns the original raw Y coordinate of this event. For touch * events on the screen, this is the original location of the event * on the screen, before it had been adjusted for the containing window * and views. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * * @see #getY(int) * @see #AXIS_Y */ public float getRawY(int pointerIndex) { return nativeGetRawAxisValue(mNativePtr, AXIS_Y, pointerIndex, HISTORY_CURRENT); } /** * Return the precision of the X coordinates being reported. You can * multiply this number with {@link #getX} to find the actual hardware * value of the X coordinate. * @return Returns the precision of X coordinates being reported. * * @see #AXIS_X */ public final float getXPrecision() { return nativeGetXPrecision(mNativePtr); } /** * Return the precision of the Y coordinates being reported. You can * multiply this number with {@link #getY} to find the actual hardware * value of the Y coordinate. * @return Returns the precision of Y coordinates being reported. * * @see #AXIS_Y */ public final float getYPrecision() { return nativeGetYPrecision(mNativePtr); } /** * Returns the x coordinate of mouse cursor position when this event is * reported. This value is only valid if {@link #getSource()} returns * {@link InputDevice#SOURCE_MOUSE}. * * @hide */ public float getXCursorPosition() { return nativeGetXCursorPosition(mNativePtr); } /** * Returns the y coordinate of mouse cursor position when this event is * reported. This value is only valid if {@link #getSource()} returns * {@link InputDevice#SOURCE_MOUSE}. * * @hide */ public float getYCursorPosition() { return nativeGetYCursorPosition(mNativePtr); } /** * Sets cursor position to given coordinates. The coordinate in parameters should be after * offsetting. In other words, the effect of this function is {@link #getXCursorPosition()} and * {@link #getYCursorPosition()} will return the same value passed in the parameters. * * @hide */ private void setCursorPosition(float x, float y) { nativeSetCursorPosition(mNativePtr, x, y); } /** * Returns the number of historical points in this event. These are * movements that have occurred between this event and the previous event. * This only applies to ACTION_MOVE events -- all other actions will have * a size of 0. * * @return Returns the number of historical points in the event. */ public final int getHistorySize() { return nativeGetHistorySize(mNativePtr); } /** * Returns the time that a historical movement occurred between this event * and the previous event, in the {@link android.os.SystemClock#uptimeMillis} time base. ** This only applies to ACTION_MOVE events. *
* * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * @return Returns the time that a historical movement occurred between this * event and the previous event, * in the {@link android.os.SystemClock#uptimeMillis} time base. * * @see #getHistorySize * @see #getEventTime */ public final long getHistoricalEventTime(int pos) { return nativeGetEventTimeNanos(mNativePtr, pos) / NS_PER_MS; } /** * Returns the time that a historical movement occurred between this event * and the previous event, in the {@link android.os.SystemClock#uptimeMillis} time base * but with nanosecond (instead of millisecond) precision. ** This only applies to ACTION_MOVE events. *
* The value is in nanosecond precision but it may not have nanosecond accuracy. *
* * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * @return Returns the time that a historical movement occurred between this * event and the previous event, * in the {@link android.os.SystemClock#uptimeMillis} time base but with * nanosecond (instead of millisecond) precision. * * @see #getHistorySize * @see #getEventTime * * @hide */ public final long getHistoricalEventTimeNano(int pos) { return nativeGetEventTimeNanos(mNativePtr, pos); } /** * {@link #getHistoricalX(int, int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getX() * @see #AXIS_X */ public final float getHistoricalX(int pos) { return nativeGetAxisValue(mNativePtr, AXIS_X, 0, pos); } /** * {@link #getHistoricalY(int, int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getY() * @see #AXIS_Y */ public final float getHistoricalY(int pos) { return nativeGetAxisValue(mNativePtr, AXIS_Y, 0, pos); } /** * {@link #getHistoricalPressure(int, int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getPressure() * @see #AXIS_PRESSURE */ public final float getHistoricalPressure(int pos) { return nativeGetAxisValue(mNativePtr, AXIS_PRESSURE, 0, pos); } /** * {@link #getHistoricalSize(int, int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getSize() * @see #AXIS_SIZE */ public final float getHistoricalSize(int pos) { return nativeGetAxisValue(mNativePtr, AXIS_SIZE, 0, pos); } /** * {@link #getHistoricalTouchMajor(int, int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getTouchMajor() * @see #AXIS_TOUCH_MAJOR */ public final float getHistoricalTouchMajor(int pos) { return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MAJOR, 0, pos); } /** * {@link #getHistoricalTouchMinor(int, int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getTouchMinor() * @see #AXIS_TOUCH_MINOR */ public final float getHistoricalTouchMinor(int pos) { return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MINOR, 0, pos); } /** * {@link #getHistoricalToolMajor(int, int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getToolMajor() * @see #AXIS_TOOL_MAJOR */ public final float getHistoricalToolMajor(int pos) { return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MAJOR, 0, pos); } /** * {@link #getHistoricalToolMinor(int, int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getToolMinor() * @see #AXIS_TOOL_MINOR */ public final float getHistoricalToolMinor(int pos) { return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MINOR, 0, pos); } /** * {@link #getHistoricalOrientation(int, int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getOrientation() * @see #AXIS_ORIENTATION */ public final float getHistoricalOrientation(int pos) { return nativeGetAxisValue(mNativePtr, AXIS_ORIENTATION, 0, pos); } /** * {@link #getHistoricalAxisValue(int, int, int)} for the first pointer index (may be an * arbitrary pointer identifier). * * @param axis The axis identifier for the axis value to retrieve. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getAxisValue(int) * @see #AXIS_X * @see #AXIS_Y */ public final float getHistoricalAxisValue(int axis, int pos) { return nativeGetAxisValue(mNativePtr, axis, 0, pos); } /** * Returns a historical X coordinate, as per {@link #getX(int)}, that * occurred between this event and the previous event for the given pointer. * Only applies to ACTION_MOVE events. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getX(int) * @see #AXIS_X */ public final float getHistoricalX(int pointerIndex, int pos) { return nativeGetAxisValue(mNativePtr, AXIS_X, pointerIndex, pos); } /** * Returns a historical Y coordinate, as per {@link #getY(int)}, that * occurred between this event and the previous event for the given pointer. * Only applies to ACTION_MOVE events. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getY(int) * @see #AXIS_Y */ public final float getHistoricalY(int pointerIndex, int pos) { return nativeGetAxisValue(mNativePtr, AXIS_Y, pointerIndex, pos); } /** * Returns a historical pressure coordinate, as per {@link #getPressure(int)}, * that occurred between this event and the previous event for the given * pointer. Only applies to ACTION_MOVE events. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getPressure(int) * @see #AXIS_PRESSURE */ public final float getHistoricalPressure(int pointerIndex, int pos) { return nativeGetAxisValue(mNativePtr, AXIS_PRESSURE, pointerIndex, pos); } /** * Returns a historical size coordinate, as per {@link #getSize(int)}, that * occurred between this event and the previous event for the given pointer. * Only applies to ACTION_MOVE events. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getSize(int) * @see #AXIS_SIZE */ public final float getHistoricalSize(int pointerIndex, int pos) { return nativeGetAxisValue(mNativePtr, AXIS_SIZE, pointerIndex, pos); } /** * Returns a historical touch major axis coordinate, as per {@link #getTouchMajor(int)}, that * occurred between this event and the previous event for the given pointer. * Only applies to ACTION_MOVE events. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getTouchMajor(int) * @see #AXIS_TOUCH_MAJOR */ public final float getHistoricalTouchMajor(int pointerIndex, int pos) { return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MAJOR, pointerIndex, pos); } /** * Returns a historical touch minor axis coordinate, as per {@link #getTouchMinor(int)}, that * occurred between this event and the previous event for the given pointer. * Only applies to ACTION_MOVE events. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getTouchMinor(int) * @see #AXIS_TOUCH_MINOR */ public final float getHistoricalTouchMinor(int pointerIndex, int pos) { return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MINOR, pointerIndex, pos); } /** * Returns a historical tool major axis coordinate, as per {@link #getToolMajor(int)}, that * occurred between this event and the previous event for the given pointer. * Only applies to ACTION_MOVE events. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getToolMajor(int) * @see #AXIS_TOOL_MAJOR */ public final float getHistoricalToolMajor(int pointerIndex, int pos) { return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MAJOR, pointerIndex, pos); } /** * Returns a historical tool minor axis coordinate, as per {@link #getToolMinor(int)}, that * occurred between this event and the previous event for the given pointer. * Only applies to ACTION_MOVE events. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getToolMinor(int) * @see #AXIS_TOOL_MINOR */ public final float getHistoricalToolMinor(int pointerIndex, int pos) { return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MINOR, pointerIndex, pos); } /** * Returns a historical orientation coordinate, as per {@link #getOrientation(int)}, that * occurred between this event and the previous event for the given pointer. * Only applies to ACTION_MOVE events. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getOrientation(int) * @see #AXIS_ORIENTATION */ public final float getHistoricalOrientation(int pointerIndex, int pos) { return nativeGetAxisValue(mNativePtr, AXIS_ORIENTATION, pointerIndex, pos); } /** * Returns the historical value of the requested axis, as per {@link #getAxisValue(int, int)}, * occurred between this event and the previous event for the given pointer. * Only applies to ACTION_MOVE events. * * @param axis The axis identifier for the axis value to retrieve. * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * @return The value of the axis, or 0 if the axis is not available. * * @see #AXIS_X * @see #AXIS_Y */ public final float getHistoricalAxisValue(int axis, int pointerIndex, int pos) { return nativeGetAxisValue(mNativePtr, axis, pointerIndex, pos); } /** * Populates a {@link PointerCoords} object with historical pointer coordinate data, * as per {@link #getPointerCoords}, that occurred between this event and the previous * event for the given pointer. * Only applies to ACTION_MOVE events. * * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * @param outPointerCoords The pointer coordinate object to populate. * * @see #getHistorySize * @see #getPointerCoords * @see PointerCoords */ public final void getHistoricalPointerCoords(int pointerIndex, int pos, PointerCoords outPointerCoords) { nativeGetPointerCoords(mNativePtr, pointerIndex, pos, outPointerCoords); } /** * Returns a bitfield indicating which edges, if any, were touched by this * MotionEvent. For touch events, clients can use this to determine if the * user's finger was touching the edge of the display. * * This property is only set for {@link #ACTION_DOWN} events. * * @see #EDGE_LEFT * @see #EDGE_TOP * @see #EDGE_RIGHT * @see #EDGE_BOTTOM */ public final int getEdgeFlags() { return nativeGetEdgeFlags(mNativePtr); } /** * Sets the bitfield indicating which edges, if any, were touched by this * MotionEvent. * * @see #getEdgeFlags() */ public final void setEdgeFlags(int flags) { nativeSetEdgeFlags(mNativePtr, flags); } /** * Sets this event's action. */ public final void setAction(int action) { nativeSetAction(mNativePtr, action); } /** * Adjust this event's location. * @param deltaX Amount to add to the current X coordinate of the event. * @param deltaY Amount to add to the current Y coordinate of the event. */ public final void offsetLocation(float deltaX, float deltaY) { if (deltaX != 0.0f || deltaY != 0.0f) { nativeOffsetLocation(mNativePtr, deltaX, deltaY); } } /** * Set this event's location. Applies {@link #offsetLocation} with a * delta from the current location to the given new location. * * @param x New absolute X location. * @param y New absolute Y location. */ public final void setLocation(float x, float y) { float oldX = getX(); float oldY = getY(); offsetLocation(x - oldX, y - oldY); } /** * Applies a transformation matrix to all of the points in the event. * * @param matrix The transformation matrix to apply. */ public final void transform(Matrix matrix) { if (matrix == null) { throw new IllegalArgumentException("matrix must not be null"); } nativeTransform(mNativePtr, matrix); } /** * Transforms all of the points in the event directly instead of modifying the event's * internal transform. * * @param matrix The transformation matrix to apply. * @hide */ public void applyTransform(Matrix matrix) { if (matrix == null) { throw new IllegalArgumentException("matrix must not be null"); } nativeApplyTransform(mNativePtr, matrix); } /** * Add a new movement to the batch of movements in this event. The event's * current location, position and size is updated to the new values. * The current values in the event are added to a list of historical values. * * Only applies to {@link #ACTION_MOVE} or {@link #ACTION_HOVER_MOVE} events. * * @param eventTime The time stamp (in ms) for this data. * @param x The new X position. * @param y The new Y position. * @param pressure The new pressure. * @param size The new size. * @param metaState Meta key state. */ public final void addBatch(long eventTime, float x, float y, float pressure, float size, int metaState) { synchronized (gSharedTempLock) { ensureSharedTempPointerCapacity(1); final PointerCoords[] pc = gSharedTempPointerCoords; pc[0].clear(); pc[0].x = x; pc[0].y = y; pc[0].pressure = pressure; pc[0].size = size; nativeAddBatch(mNativePtr, eventTime * NS_PER_MS, pc, metaState); } } /** * Add a new movement to the batch of movements in this event. The event's * current location, position and size is updated to the new values. * The current values in the event are added to a list of historical values. * * Only applies to {@link #ACTION_MOVE} or {@link #ACTION_HOVER_MOVE} events. * * @param eventTime The time stamp (in ms) for this data. * @param pointerCoords The new pointer coordinates. * @param metaState Meta key state. */ public final void addBatch(long eventTime, PointerCoords[] pointerCoords, int metaState) { nativeAddBatch(mNativePtr, eventTime * NS_PER_MS, pointerCoords, metaState); } /** * Adds all of the movement samples of the specified event to this one if * it is compatible. To be compatible, the event must have the same device id, * source, display id, action, flags, classification, pointer count, pointer properties. * * Only applies to {@link #ACTION_MOVE} or {@link #ACTION_HOVER_MOVE} events. * * @param event The event whose movements samples should be added to this one * if possible. * @return True if batching was performed or false if batching was not possible. * @hide */ @UnsupportedAppUsage public final boolean addBatch(MotionEvent event) { final int action = nativeGetAction(mNativePtr); if (action != ACTION_MOVE && action != ACTION_HOVER_MOVE) { return false; } if (action != nativeGetAction(event.mNativePtr)) { return false; } if (nativeGetDeviceId(mNativePtr) != nativeGetDeviceId(event.mNativePtr) || nativeGetSource(mNativePtr) != nativeGetSource(event.mNativePtr) || nativeGetDisplayId(mNativePtr) != nativeGetDisplayId(event.mNativePtr) || nativeGetFlags(mNativePtr) != nativeGetFlags(event.mNativePtr) || nativeGetClassification(mNativePtr) != nativeGetClassification(event.mNativePtr)) { return false; } final int pointerCount = nativeGetPointerCount(mNativePtr); if (pointerCount != nativeGetPointerCount(event.mNativePtr)) { return false; } synchronized (gSharedTempLock) { ensureSharedTempPointerCapacity(Math.max(pointerCount, 2)); final PointerProperties[] pp = gSharedTempPointerProperties; final PointerCoords[] pc = gSharedTempPointerCoords; for (int i = 0; i < pointerCount; i++) { nativeGetPointerProperties(mNativePtr, i, pp[0]); nativeGetPointerProperties(event.mNativePtr, i, pp[1]); if (!pp[0].equals(pp[1])) { return false; } } final int metaState = nativeGetMetaState(event.mNativePtr); final int historySize = nativeGetHistorySize(event.mNativePtr); for (int h = 0; h <= historySize; h++) { final int historyPos = (h == historySize ? HISTORY_CURRENT : h); for (int i = 0; i < pointerCount; i++) { nativeGetPointerCoords(event.mNativePtr, i, historyPos, pc[i]); } final long eventTimeNanos = nativeGetEventTimeNanos(event.mNativePtr, historyPos); nativeAddBatch(mNativePtr, eventTimeNanos, pc, metaState); } } return true; } /** * Returns true if all points in the motion event are completely within the specified bounds. * @hide */ public final boolean isWithinBoundsNoHistory(float left, float top, float right, float bottom) { final int pointerCount = nativeGetPointerCount(mNativePtr); for (int i = 0; i < pointerCount; i++) { final float x = nativeGetAxisValue(mNativePtr, AXIS_X, i, HISTORY_CURRENT); final float y = nativeGetAxisValue(mNativePtr, AXIS_Y, i, HISTORY_CURRENT); if (x < left || x > right || y < top || y > bottom) { return false; } } return true; } private static final float clamp(float value, float low, float high) { if (value < low) { return low; } else if (value > high) { return high; } return value; } /** * Returns a new motion events whose points have been clamped to the specified bounds. * @hide */ public final MotionEvent clampNoHistory(float left, float top, float right, float bottom) { MotionEvent ev = obtain(); synchronized (gSharedTempLock) { final int pointerCount = nativeGetPointerCount(mNativePtr); ensureSharedTempPointerCapacity(pointerCount); final PointerProperties[] pp = gSharedTempPointerProperties; final PointerCoords[] pc = gSharedTempPointerCoords; for (int i = 0; i < pointerCount; i++) { nativeGetPointerProperties(mNativePtr, i, pp[i]); nativeGetPointerCoords(mNativePtr, i, HISTORY_CURRENT, pc[i]); pc[i].x = clamp(pc[i].x, left, right); pc[i].y = clamp(pc[i].y, top, bottom); } ev.initialize(nativeGetDeviceId(mNativePtr), nativeGetSource(mNativePtr), nativeGetDisplayId(mNativePtr), nativeGetAction(mNativePtr), nativeGetFlags(mNativePtr), nativeGetEdgeFlags(mNativePtr), nativeGetMetaState(mNativePtr), nativeGetButtonState(mNativePtr), nativeGetClassification(mNativePtr), nativeGetXOffset(mNativePtr), nativeGetYOffset(mNativePtr), nativeGetXPrecision(mNativePtr), nativeGetYPrecision(mNativePtr), nativeGetDownTimeNanos(mNativePtr), nativeGetEventTimeNanos(mNativePtr, HISTORY_CURRENT), pointerCount, pp, pc); return ev; } } /** * Gets an integer where each pointer id present in the event is marked as a bit. * @hide */ @UnsupportedAppUsage public final int getPointerIdBits() { int idBits = 0; final int pointerCount = nativeGetPointerCount(mNativePtr); for (int i = 0; i < pointerCount; i++) { idBits |= 1 << nativeGetPointerId(mNativePtr, i); } return idBits; } /** * Splits a motion event such that it includes only a subset of pointer ids. * @hide */ @UnsupportedAppUsage public final MotionEvent split(int idBits) { MotionEvent ev = obtain(); synchronized (gSharedTempLock) { final int oldPointerCount = nativeGetPointerCount(mNativePtr); ensureSharedTempPointerCapacity(oldPointerCount); final PointerProperties[] pp = gSharedTempPointerProperties; final PointerCoords[] pc = gSharedTempPointerCoords; final int[] map = gSharedTempPointerIndexMap; final int oldAction = nativeGetAction(mNativePtr); final int oldActionMasked = oldAction & ACTION_MASK; final int oldActionPointerIndex = (oldAction & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT; int newActionPointerIndex = -1; int newPointerCount = 0; for (int i = 0; i < oldPointerCount; i++) { nativeGetPointerProperties(mNativePtr, i, pp[newPointerCount]); final int idBit = 1 << pp[newPointerCount].id; if ((idBit & idBits) != 0) { if (i == oldActionPointerIndex) { newActionPointerIndex = newPointerCount; } map[newPointerCount] = i; newPointerCount += 1; } } if (newPointerCount == 0) { throw new IllegalArgumentException("idBits did not match any ids in the event"); } final int newAction; if (oldActionMasked == ACTION_POINTER_DOWN || oldActionMasked == ACTION_POINTER_UP) { if (newActionPointerIndex < 0) { // An unrelated pointer changed. newAction = ACTION_MOVE; } else if (newPointerCount == 1) { // The first/last pointer went down/up. newAction = oldActionMasked == ACTION_POINTER_DOWN ? ACTION_DOWN : (getFlags() & FLAG_CANCELED) == 0 ? ACTION_UP : ACTION_CANCEL; } else { // A secondary pointer went down/up. newAction = oldActionMasked | (newActionPointerIndex << ACTION_POINTER_INDEX_SHIFT); } } else { // Simple up/down/cancel/move or other motion action. newAction = oldAction; } final int historySize = nativeGetHistorySize(mNativePtr); for (int h = 0; h <= historySize; h++) { final int historyPos = h == historySize ? HISTORY_CURRENT : h; for (int i = 0; i < newPointerCount; i++) { nativeGetPointerCoords(mNativePtr, map[i], historyPos, pc[i]); } final long eventTimeNanos = nativeGetEventTimeNanos(mNativePtr, historyPos); if (h == 0) { ev.initialize(nativeGetDeviceId(mNativePtr), nativeGetSource(mNativePtr), nativeGetDisplayId(mNativePtr), newAction, nativeGetFlags(mNativePtr), nativeGetEdgeFlags(mNativePtr), nativeGetMetaState(mNativePtr), nativeGetButtonState(mNativePtr), nativeGetClassification(mNativePtr), nativeGetXOffset(mNativePtr), nativeGetYOffset(mNativePtr), nativeGetXPrecision(mNativePtr), nativeGetYPrecision(mNativePtr), nativeGetDownTimeNanos(mNativePtr), eventTimeNanos, newPointerCount, pp, pc); } else { nativeAddBatch(ev.mNativePtr, eventTimeNanos, pc, 0); } } return ev; } } /** * Calculate new cursor position for events from mouse. This is used to split, clamp and inject * events. * *If the source is mouse, it sets cursor position to the centroid of all pointers because * InputReader maps multiple fingers on a touchpad to locations around cursor position in screen * coordinates so that the mouse cursor is at the centroid of all pointers. * *
If the source is not mouse it sets cursor position to NaN.
*/
private void updateCursorPosition() {
if (getSource() != InputDevice.SOURCE_MOUSE) {
setCursorPosition(INVALID_CURSOR_POSITION, INVALID_CURSOR_POSITION);
return;
}
float x = 0;
float y = 0;
final int pointerCount = getPointerCount();
for (int i = 0; i < pointerCount; ++i) {
x += getX(i);
y += getY(i);
}
// If pointer count is 0, divisions below yield NaN, which is an acceptable result for this
// corner case.
x /= pointerCount;
y /= pointerCount;
setCursorPosition(x, y);
}
@Override
public String toString() {
StringBuilder msg = new StringBuilder();
msg.append("MotionEvent { action=").append(actionToString(getAction()));
appendUnless("0", msg, ", actionButton=", buttonStateToString(getActionButton()));
final int pointerCount = getPointerCount();
for (int i = 0; i < pointerCount; i++) {
appendUnless(i, msg, ", id[" + i + "]=", getPointerId(i));
float x = getX(i);
float y = getY(i);
if (!DEBUG_CONCISE_TOSTRING || x != 0f || y != 0f) {
msg.append(", x[").append(i).append("]=").append(x);
msg.append(", y[").append(i).append("]=").append(y);
}
appendUnless(TOOL_TYPE_SYMBOLIC_NAMES.get(TOOL_TYPE_FINGER),
msg, ", toolType[" + i + "]=", toolTypeToString(getToolType(i)));
}
appendUnless("0", msg, ", buttonState=", MotionEvent.buttonStateToString(getButtonState()));
appendUnless(classificationToString(CLASSIFICATION_NONE), msg, ", classification=",
classificationToString(getClassification()));
appendUnless("0", msg, ", metaState=", KeyEvent.metaStateToString(getMetaState()));
appendUnless("0", msg, ", flags=0x", Integer.toHexString(getFlags()));
appendUnless("0", msg, ", edgeFlags=0x", Integer.toHexString(getEdgeFlags()));
appendUnless(1, msg, ", pointerCount=", pointerCount);
appendUnless(0, msg, ", historySize=", getHistorySize());
msg.append(", eventTime=").append(getEventTime());
if (!DEBUG_CONCISE_TOSTRING) {
msg.append(", downTime=").append(getDownTime());
msg.append(", deviceId=").append(getDeviceId());
msg.append(", source=0x").append(Integer.toHexString(getSource()));
msg.append(", displayId=").append(getDisplayId());
msg.append(", eventId=").append(getId());
}
msg.append(" }");
return msg.toString();
}
private static