blob: b2f0c60b0b302ff1c83eb5a057514285c4ddd1b9 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.view;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21import android.os.SystemClock;
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -070022import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023
24/**
25 * Object used to report movement (mouse, pen, finger, trackball) events. This
26 * class may hold either absolute or relative movements, depending on what
27 * it is being used for.
28 */
29public final class MotionEvent implements Parcelable {
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -070030 static final boolean DEBUG_POINTERS = false;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032 /**
Dianne Hackborn9822d2b2009-07-20 17:33:15 -070033 * Bit mask of the parts of the action code that are the action itself.
34 */
35 public static final int ACTION_MASK = 0xff;
36
37 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038 * Constant for {@link #getAction}: A pressed gesture has started, the
39 * motion contains the initial starting location.
40 */
41 public static final int ACTION_DOWN = 0;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -070042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043 /**
44 * Constant for {@link #getAction}: A pressed gesture has finished, the
45 * motion contains the final release location as well as any intermediate
46 * points since the last down or move event.
47 */
48 public static final int ACTION_UP = 1;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -070049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 /**
51 * Constant for {@link #getAction}: A change has happened during a
52 * press gesture (between {@link #ACTION_DOWN} and {@link #ACTION_UP}).
53 * The motion contains the most recent point, as well as any intermediate
54 * points since the last down or move event.
55 */
56 public static final int ACTION_MOVE = 2;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -070057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 /**
59 * Constant for {@link #getAction}: The current gesture has been aborted.
60 * You will not receive any more points in it. You should treat this as
61 * an up event, but not perform any action that you normally would.
62 */
63 public static final int ACTION_CANCEL = 3;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -070064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065 /**
66 * Constant for {@link #getAction}: A movement has happened outside of the
67 * normal bounds of the UI element. This does not provide a full gesture,
68 * but only the initial location of the movement/touch.
69 */
70 public static final int ACTION_OUTSIDE = 4;
71
Dianne Hackborn9822d2b2009-07-20 17:33:15 -070072 /**
73 * A non-primary pointer has gone down. The bits in
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -070074 * {@link #ACTION_POINTER_ID_MASK} indicate which pointer changed.
Dianne Hackborn9822d2b2009-07-20 17:33:15 -070075 */
76 public static final int ACTION_POINTER_DOWN = 5;
77
78 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -070079 * Synonym for {@link #ACTION_POINTER_DOWN} with
80 * {@link #ACTION_POINTER_ID_MASK} of 0: the primary pointer has gone done.
Dianne Hackborn9822d2b2009-07-20 17:33:15 -070081 */
82 public static final int ACTION_POINTER_1_DOWN = ACTION_POINTER_DOWN | 0x0000;
83
84 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -070085 * Synonym for {@link #ACTION_POINTER_DOWN} with
86 * {@link #ACTION_POINTER_ID_MASK} of 1: the secondary pointer has gone done.
Dianne Hackborn9822d2b2009-07-20 17:33:15 -070087 */
88 public static final int ACTION_POINTER_2_DOWN = ACTION_POINTER_DOWN | 0x0100;
89
90 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -070091 * Synonym for {@link #ACTION_POINTER_DOWN} with
92 * {@link #ACTION_POINTER_ID_MASK} of 2: the tertiary pointer has gone done.
Dianne Hackborn9822d2b2009-07-20 17:33:15 -070093 */
94 public static final int ACTION_POINTER_3_DOWN = ACTION_POINTER_DOWN | 0x0200;
95
96 /**
97 * A non-primary pointer has gone up. The bits in
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -070098 * {@link #ACTION_POINTER_ID_MASK} indicate which pointer changed.
Dianne Hackborn9822d2b2009-07-20 17:33:15 -070099 */
100 public static final int ACTION_POINTER_UP = 6;
101
102 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700103 * Synonym for {@link #ACTION_POINTER_UP} with
104 * {@link #ACTION_POINTER_ID_MASK} of 0: the primary pointer has gone up.
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700105 */
106 public static final int ACTION_POINTER_1_UP = ACTION_POINTER_UP | 0x0000;
107
108 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700109 * Synonym for {@link #ACTION_POINTER_UP} with
110 * {@link #ACTION_POINTER_ID_MASK} of 1: the secondary pointer has gone up.
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700111 */
112 public static final int ACTION_POINTER_2_UP = ACTION_POINTER_UP | 0x0100;
113
114 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700115 * Synonym for {@link #ACTION_POINTER_UP} with
116 * {@link #ACTION_POINTER_ID_MASK} of 2: the tertiary pointer has gone up.
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700117 */
118 public static final int ACTION_POINTER_3_UP = ACTION_POINTER_UP | 0x0200;
119
120 /**
121 * Bits in the action code that represent a pointer ID, used with
122 * {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}. Pointer IDs
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700123 * start at 0, with 0 being the primary (first) pointer in the motion. Note
124 * that this not <em>not</em> an index into the array of pointer values,
125 * which is compacted to only contain pointers that are down; the pointer
126 * ID for a particular index can be found with {@link #findPointerIndex}.
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700127 */
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700128 public static final int ACTION_POINTER_ID_MASK = 0xff00;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700129
130 /**
131 * Bit shift for the action bits holding the pointer identifier as
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700132 * defined by {@link #ACTION_POINTER_ID_MASK}.
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700133 */
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700134 public static final int ACTION_POINTER_ID_SHIFT = 8;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 private static final boolean TRACK_RECYCLED_LOCATION = false;
Romain Guycafdea62009-06-12 10:51:36 -0700137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 /**
139 * Flag indicating the motion event intersected the top edge of the screen.
140 */
141 public static final int EDGE_TOP = 0x00000001;
Romain Guycafdea62009-06-12 10:51:36 -0700142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 /**
144 * Flag indicating the motion event intersected the bottom edge of the screen.
145 */
146 public static final int EDGE_BOTTOM = 0x00000002;
Romain Guycafdea62009-06-12 10:51:36 -0700147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 /**
149 * Flag indicating the motion event intersected the left edge of the screen.
150 */
151 public static final int EDGE_LEFT = 0x00000004;
Romain Guycafdea62009-06-12 10:51:36 -0700152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 /**
154 * Flag indicating the motion event intersected the right edge of the screen.
155 */
156 public static final int EDGE_RIGHT = 0x00000008;
Romain Guycafdea62009-06-12 10:51:36 -0700157
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700158 /**
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700159 * Offset for the sample's X coordinate.
160 * @hide
161 */
162 static public final int SAMPLE_X = 0;
163
164 /**
165 * Offset for the sample's Y coordinate.
166 * @hide
167 */
168 static public final int SAMPLE_Y = 1;
169
170 /**
171 * Offset for the sample's X coordinate.
172 * @hide
173 */
174 static public final int SAMPLE_PRESSURE = 2;
175
176 /**
177 * Offset for the sample's X coordinate.
178 * @hide
179 */
180 static public final int SAMPLE_SIZE = 3;
181
182 /**
183 * Number of data items for each sample.
184 * @hide
185 */
186 static public final int NUM_SAMPLE_DATA = 4;
187
Dianne Hackborn1e8dfc72009-08-06 12:43:01 -0700188 /**
189 * Number of possible pointers.
190 * @hide
191 */
192 static public final int BASE_AVAIL_POINTERS = 5;
193
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700194 static private final int BASE_AVAIL_SAMPLES = 8;
195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 static private final int MAX_RECYCLED = 10;
197 static private Object gRecyclerLock = new Object();
198 static private int gRecyclerUsed = 0;
199 static private MotionEvent gRecyclerTop = null;
Romain Guycafdea62009-06-12 10:51:36 -0700200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201 private long mDownTime;
Michael Chan53071d62009-05-13 17:29:48 -0700202 private long mEventTimeNano;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 private int mAction;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 private float mRawX;
205 private float mRawY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 private float mXPrecision;
207 private float mYPrecision;
208 private int mDeviceId;
209 private int mEdgeFlags;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700210 private int mMetaState;
211
212 // Here is the actual event data. Note that the order of the array
213 // is a little odd: the first entry is the most recent, and the ones
214 // following it are the historical data from oldest to newest. This
215 // allows us to easily retrieve the most recent data, without having
216 // to copy the arrays every time a new sample is added.
217
218 private int mNumPointers;
219 private int mNumSamples;
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700220 // Array of mNumPointers size of identifiers for each pointer of data.
221 private int[] mPointerIdentifiers;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700222 // Array of (mNumSamples * mNumPointers * NUM_SAMPLE_DATA) size of event data.
223 private float[] mDataSamples;
224 // Array of mNumSamples size of time stamps.
225 private long[] mTimeSamples;
Mitsuru Oshima8169dae2009-04-28 18:12:09 -0700226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 private MotionEvent mNext;
228 private RuntimeException mRecycledLocation;
229 private boolean mRecycled;
230
231 private MotionEvent() {
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700232 mPointerIdentifiers = new int[BASE_AVAIL_POINTERS];
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700233 mDataSamples = new float[BASE_AVAIL_POINTERS*BASE_AVAIL_SAMPLES*NUM_SAMPLE_DATA];
234 mTimeSamples = new long[BASE_AVAIL_SAMPLES];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 }
Romain Guycafdea62009-06-12 10:51:36 -0700236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237 static private MotionEvent obtain() {
238 synchronized (gRecyclerLock) {
239 if (gRecyclerTop == null) {
240 return new MotionEvent();
241 }
242 MotionEvent ev = gRecyclerTop;
243 gRecyclerTop = ev.mNext;
244 gRecyclerUsed--;
245 ev.mRecycledLocation = null;
246 ev.mRecycled = false;
247 return ev;
248 }
249 }
Michael Chan53071d62009-05-13 17:29:48 -0700250
251 /**
252 * Create a new MotionEvent, filling in all of the basic values that
253 * define the motion.
254 *
255 * @param downTime The time (in ms) when the user originally pressed down to start
256 * a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
257 * @param eventTime The the time (in ms) when this specific event was generated. This
258 * must be obtained from {@link SystemClock#uptimeMillis()}.
259 * @param eventTimeNano The the time (in ns) when this specific event was generated. This
260 * must be obtained from {@link System#nanoTime()}.
261 * @param action The kind of action being performed -- one of either
262 * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
263 * {@link #ACTION_CANCEL}.
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700264 * @param pointers The number of points that will be in this event.
265 * @param inPointerIds An array of <em>pointers</em> values providing
266 * an identifier for each pointer.
267 * @param inData An array of <em>pointers*NUM_SAMPLE_DATA</em> of initial
268 * data samples for the event.
Michael Chan53071d62009-05-13 17:29:48 -0700269 * @param metaState The state of any meta / modifier keys that were in effect when
270 * the event was generated.
271 * @param xPrecision The precision of the X coordinate being reported.
272 * @param yPrecision The precision of the Y coordinate being reported.
273 * @param deviceId The id for the device that this event came from. An id of
274 * zero indicates that the event didn't come from a physical device; other
275 * numbers are arbitrary and you shouldn't depend on the values.
276 * @param edgeFlags A bitfield indicating which edges, if any, where touched by this
277 * MotionEvent.
278 *
279 * @hide
280 */
281 static public MotionEvent obtainNano(long downTime, long eventTime, long eventTimeNano,
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700282 int action, int pointers, int[] inPointerIds, float[] inData, int metaState,
Michael Chan53071d62009-05-13 17:29:48 -0700283 float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
284 MotionEvent ev = obtain();
285 ev.mDeviceId = deviceId;
286 ev.mEdgeFlags = edgeFlags;
287 ev.mDownTime = downTime;
Michael Chan53071d62009-05-13 17:29:48 -0700288 ev.mEventTimeNano = eventTimeNano;
289 ev.mAction = action;
Michael Chan53071d62009-05-13 17:29:48 -0700290 ev.mMetaState = metaState;
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700291 ev.mRawX = inData[SAMPLE_X];
292 ev.mRawY = inData[SAMPLE_Y];
Michael Chan53071d62009-05-13 17:29:48 -0700293 ev.mXPrecision = xPrecision;
294 ev.mYPrecision = yPrecision;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700295 ev.mNumPointers = pointers;
296 ev.mNumSamples = 1;
297
Dianne Hackborn1e8dfc72009-08-06 12:43:01 -0700298 int[] pointerIdentifiers = ev.mPointerIdentifiers;
299 if (pointerIdentifiers.length < pointers) {
300 ev.mPointerIdentifiers = pointerIdentifiers = new int[pointers];
301 }
302 System.arraycopy(inPointerIds, 0, pointerIdentifiers, 0, pointers);
303
304 final int ND = pointers * NUM_SAMPLE_DATA;
305 float[] dataSamples = ev.mDataSamples;
306 if (dataSamples.length < ND) {
307 ev.mDataSamples = dataSamples = new float[ND];
308 }
309 System.arraycopy(inData, 0, dataSamples, 0, ND);
310
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700311 ev.mTimeSamples[0] = eventTime;
Michael Chan53071d62009-05-13 17:29:48 -0700312
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700313 if (DEBUG_POINTERS) {
314 StringBuilder sb = new StringBuilder(128);
315 sb.append("New:");
316 for (int i=0; i<pointers; i++) {
317 sb.append(" #");
318 sb.append(ev.mPointerIdentifiers[i]);
319 sb.append("(");
320 sb.append(ev.mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_X]);
321 sb.append(",");
322 sb.append(ev.mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_Y]);
323 sb.append(")");
324 }
325 Log.v("MotionEvent", sb.toString());
326 }
327
Michael Chan53071d62009-05-13 17:29:48 -0700328 return ev;
329 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330
331 /**
332 * Create a new MotionEvent, filling in all of the basic values that
333 * define the motion.
Romain Guycafdea62009-06-12 10:51:36 -0700334 *
335 * @param downTime The time (in ms) when the user originally pressed down to start
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 * a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
Romain Guycafdea62009-06-12 10:51:36 -0700337 * @param eventTime The the time (in ms) when this specific event was generated. This
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 * must be obtained from {@link SystemClock#uptimeMillis()}.
339 * @param action The kind of action being performed -- one of either
340 * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
341 * {@link #ACTION_CANCEL}.
342 * @param x The X coordinate of this event.
343 * @param y The Y coordinate of this event.
Romain Guycafdea62009-06-12 10:51:36 -0700344 * @param pressure The current pressure of this event. The pressure generally
345 * ranges from 0 (no pressure at all) to 1 (normal pressure), however
346 * values higher than 1 may be generated depending on the calibration of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 * the input device.
348 * @param size A scaled value of the approximate size of the area being pressed when
Romain Guycafdea62009-06-12 10:51:36 -0700349 * touched with the finger. The actual value in pixels corresponding to the finger
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 * touch is normalized with a device specific range of values
351 * and scaled to a value between 0 and 1.
352 * @param metaState The state of any meta / modifier keys that were in effect when
353 * the event was generated.
354 * @param xPrecision The precision of the X coordinate being reported.
355 * @param yPrecision The precision of the Y coordinate being reported.
356 * @param deviceId The id for the device that this event came from. An id of
357 * zero indicates that the event didn't come from a physical device; other
358 * numbers are arbitrary and you shouldn't depend on the values.
359 * @param edgeFlags A bitfield indicating which edges, if any, where touched by this
360 * MotionEvent.
361 */
362 static public MotionEvent obtain(long downTime, long eventTime, int action,
363 float x, float y, float pressure, float size, int metaState,
364 float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
365 MotionEvent ev = obtain();
366 ev.mDeviceId = deviceId;
367 ev.mEdgeFlags = edgeFlags;
368 ev.mDownTime = downTime;
Michael Chan53071d62009-05-13 17:29:48 -0700369 ev.mEventTimeNano = eventTime * 1000000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 ev.mAction = action;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 ev.mMetaState = metaState;
372 ev.mXPrecision = xPrecision;
373 ev.mYPrecision = yPrecision;
374
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700375 ev.mNumPointers = 1;
376 ev.mNumSamples = 1;
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700377 int[] pointerIds = ev.mPointerIdentifiers;
378 pointerIds[0] = 0;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700379 float[] data = ev.mDataSamples;
380 data[SAMPLE_X] = ev.mRawX = x;
381 data[SAMPLE_Y] = ev.mRawY = y;
382 data[SAMPLE_PRESSURE] = pressure;
383 data[SAMPLE_SIZE] = size;
384 ev.mTimeSamples[0] = eventTime;
385
386 return ev;
387 }
388
389 /**
390 * Create a new MotionEvent, filling in all of the basic values that
391 * define the motion.
392 *
393 * @param downTime The time (in ms) when the user originally pressed down to start
394 * a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
395 * @param eventTime The the time (in ms) when this specific event was generated. This
396 * must be obtained from {@link SystemClock#uptimeMillis()}.
397 * @param action The kind of action being performed -- one of either
398 * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
399 * {@link #ACTION_CANCEL}.
400 * @param pointers The number of pointers that are active in this event.
401 * @param x The X coordinate of this event.
402 * @param y The Y coordinate of this event.
403 * @param pressure The current pressure of this event. The pressure generally
404 * ranges from 0 (no pressure at all) to 1 (normal pressure), however
405 * values higher than 1 may be generated depending on the calibration of
406 * the input device.
407 * @param size A scaled value of the approximate size of the area being pressed when
408 * touched with the finger. The actual value in pixels corresponding to the finger
409 * touch is normalized with a device specific range of values
410 * and scaled to a value between 0 and 1.
411 * @param metaState The state of any meta / modifier keys that were in effect when
412 * the event was generated.
413 * @param xPrecision The precision of the X coordinate being reported.
414 * @param yPrecision The precision of the Y coordinate being reported.
415 * @param deviceId The id for the device that this event came from. An id of
416 * zero indicates that the event didn't come from a physical device; other
417 * numbers are arbitrary and you shouldn't depend on the values.
418 * @param edgeFlags A bitfield indicating which edges, if any, where touched by this
419 * MotionEvent.
420 */
421 static public MotionEvent obtain(long downTime, long eventTime, int action,
422 int pointers, float x, float y, float pressure, float size, int metaState,
423 float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
424 MotionEvent ev = obtain();
425 ev.mDeviceId = deviceId;
426 ev.mEdgeFlags = edgeFlags;
427 ev.mDownTime = downTime;
428 ev.mEventTimeNano = eventTime * 1000000;
429 ev.mAction = action;
430 ev.mNumPointers = pointers;
431 ev.mMetaState = metaState;
432 ev.mXPrecision = xPrecision;
433 ev.mYPrecision = yPrecision;
434
435 ev.mNumPointers = 1;
436 ev.mNumSamples = 1;
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700437 int[] pointerIds = ev.mPointerIdentifiers;
438 pointerIds[0] = 0;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700439 float[] data = ev.mDataSamples;
440 data[SAMPLE_X] = ev.mRawX = x;
441 data[SAMPLE_Y] = ev.mRawY = y;
442 data[SAMPLE_PRESSURE] = pressure;
443 data[SAMPLE_SIZE] = size;
444 ev.mTimeSamples[0] = eventTime;
445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446 return ev;
447 }
Romain Guycafdea62009-06-12 10:51:36 -0700448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 /**
450 * Create a new MotionEvent, filling in a subset of the basic motion
451 * values. Those not specified here are: device id (always 0), pressure
452 * and size (always 1), x and y precision (always 1), and edgeFlags (always 0).
Romain Guycafdea62009-06-12 10:51:36 -0700453 *
454 * @param downTime The time (in ms) when the user originally pressed down to start
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 * a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
Romain Guycafdea62009-06-12 10:51:36 -0700456 * @param eventTime The the time (in ms) when this specific event was generated. This
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457 * must be obtained from {@link SystemClock#uptimeMillis()}.
458 * @param action The kind of action being performed -- one of either
459 * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
460 * {@link #ACTION_CANCEL}.
461 * @param x The X coordinate of this event.
462 * @param y The Y coordinate of this event.
463 * @param metaState The state of any meta / modifier keys that were in effect when
464 * the event was generated.
465 */
466 static public MotionEvent obtain(long downTime, long eventTime, int action,
467 float x, float y, int metaState) {
468 MotionEvent ev = obtain();
469 ev.mDeviceId = 0;
470 ev.mEdgeFlags = 0;
471 ev.mDownTime = downTime;
Michael Chan53071d62009-05-13 17:29:48 -0700472 ev.mEventTimeNano = eventTime * 1000000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 ev.mAction = action;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700474 ev.mNumPointers = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 ev.mMetaState = metaState;
476 ev.mXPrecision = 1.0f;
477 ev.mYPrecision = 1.0f;
478
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700479 ev.mNumPointers = 1;
480 ev.mNumSamples = 1;
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700481 int[] pointerIds = ev.mPointerIdentifiers;
482 pointerIds[0] = 0;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700483 float[] data = ev.mDataSamples;
484 data[SAMPLE_X] = ev.mRawX = x;
485 data[SAMPLE_Y] = ev.mRawY = y;
486 data[SAMPLE_PRESSURE] = 1.0f;
487 data[SAMPLE_SIZE] = 1.0f;
488 ev.mTimeSamples[0] = eventTime;
489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 return ev;
491 }
Mitsuru Oshima8169dae2009-04-28 18:12:09 -0700492
493 /**
Mitsuru Oshima64f59342009-06-21 00:03:11 -0700494 * Scales down the coordination of this event by the given scale.
Mitsuru Oshima8169dae2009-04-28 18:12:09 -0700495 *
496 * @hide
497 */
498 public void scale(float scale) {
Mitsuru Oshima64f59342009-06-21 00:03:11 -0700499 mRawX *= scale;
500 mRawY *= scale;
Mitsuru Oshima64f59342009-06-21 00:03:11 -0700501 mXPrecision *= scale;
502 mYPrecision *= scale;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700503 float[] history = mDataSamples;
504 final int length = mNumPointers * mNumSamples * NUM_SAMPLE_DATA;
505 for (int i = 0; i < length; i += NUM_SAMPLE_DATA) {
506 history[i + SAMPLE_X] *= scale;
507 history[i + SAMPLE_Y] *= scale;
508 // no need to scale pressure
509 history[i + SAMPLE_SIZE] *= scale; // TODO: square this?
Mitsuru Oshima8169dae2009-04-28 18:12:09 -0700510 }
511 }
512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 /**
514 * Create a new MotionEvent, copying from an existing one.
515 */
516 static public MotionEvent obtain(MotionEvent o) {
517 MotionEvent ev = obtain();
518 ev.mDeviceId = o.mDeviceId;
519 ev.mEdgeFlags = o.mEdgeFlags;
520 ev.mDownTime = o.mDownTime;
Michael Chan53071d62009-05-13 17:29:48 -0700521 ev.mEventTimeNano = o.mEventTimeNano;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800522 ev.mAction = o.mAction;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700523 ev.mNumPointers = o.mNumPointers;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 ev.mRawX = o.mRawX;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 ev.mRawY = o.mRawY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 ev.mMetaState = o.mMetaState;
527 ev.mXPrecision = o.mXPrecision;
528 ev.mYPrecision = o.mYPrecision;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700529
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700530 final int NS = ev.mNumSamples = o.mNumSamples;
531 if (ev.mTimeSamples.length >= NS) {
532 System.arraycopy(o.mTimeSamples, 0, ev.mTimeSamples, 0, NS);
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700533 } else {
534 ev.mTimeSamples = (long[])o.mTimeSamples.clone();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 }
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700536
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700537 final int NP = (ev.mNumPointers=o.mNumPointers);
538 if (ev.mPointerIdentifiers.length >= NP) {
539 System.arraycopy(o.mPointerIdentifiers, 0, ev.mPointerIdentifiers, 0, NP);
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700540 } else {
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700541 ev.mPointerIdentifiers = (int[])o.mPointerIdentifiers.clone();
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700542 }
543
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700544 final int ND = NP * NS * NUM_SAMPLE_DATA;
Owen Lin18a081e2009-07-29 21:26:18 +0800545 if (ev.mDataSamples.length >= ND) {
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700546 System.arraycopy(o.mDataSamples, 0, ev.mDataSamples, 0, ND);
547 } else {
548 ev.mDataSamples = (float[])o.mDataSamples.clone();
549 }
550
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 return ev;
552 }
Romain Guycafdea62009-06-12 10:51:36 -0700553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 /**
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700555 * Create a new MotionEvent, copying from an existing one, but not including
556 * any historical point information.
557 */
558 static public MotionEvent obtainNoHistory(MotionEvent o) {
559 MotionEvent ev = obtain();
560 ev.mDeviceId = o.mDeviceId;
561 ev.mEdgeFlags = o.mEdgeFlags;
562 ev.mDownTime = o.mDownTime;
563 ev.mEventTimeNano = o.mEventTimeNano;
564 ev.mAction = o.mAction;
565 ev.mNumPointers = o.mNumPointers;
566 ev.mRawX = o.mRawX;
567 ev.mRawY = o.mRawY;
568 ev.mMetaState = o.mMetaState;
569 ev.mXPrecision = o.mXPrecision;
570 ev.mYPrecision = o.mYPrecision;
571
572 ev.mNumSamples = 1;
573 ev.mTimeSamples[0] = o.mTimeSamples[0];
574
575 final int NP = (ev.mNumPointers=o.mNumPointers);
576 if (ev.mPointerIdentifiers.length >= NP) {
577 System.arraycopy(o.mPointerIdentifiers, 0, ev.mPointerIdentifiers, 0, NP);
578 } else {
579 ev.mPointerIdentifiers = (int[])o.mPointerIdentifiers.clone();
580 }
581
582 final int ND = NP * NUM_SAMPLE_DATA;
583 if (ev.mDataSamples.length >= ND) {
584 System.arraycopy(o.mDataSamples, 0, ev.mDataSamples, 0, ND);
585 } else {
586 ev.mDataSamples = (float[])o.mDataSamples.clone();
587 }
588
589 return ev;
590 }
591
592 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 * Recycle the MotionEvent, to be re-used by a later caller. After calling
594 * this function you must not ever touch the event again.
595 */
596 public void recycle() {
597 // Ensure recycle is only called once!
598 if (TRACK_RECYCLED_LOCATION) {
599 if (mRecycledLocation != null) {
600 throw new RuntimeException(toString() + " recycled twice!", mRecycledLocation);
601 }
602 mRecycledLocation = new RuntimeException("Last recycled here");
603 } else if (mRecycled) {
604 throw new RuntimeException(toString() + " recycled twice!");
605 }
606
607 //Log.w("MotionEvent", "Recycling event " + this, mRecycledLocation);
608 synchronized (gRecyclerLock) {
609 if (gRecyclerUsed < MAX_RECYCLED) {
610 gRecyclerUsed++;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700611 mNumSamples = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 mNext = gRecyclerTop;
613 gRecyclerTop = this;
614 }
615 }
616 }
Romain Guycafdea62009-06-12 10:51:36 -0700617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618 /**
619 * Return the kind of action being performed -- one of either
620 * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
621 * {@link #ACTION_CANCEL}.
622 */
623 public final int getAction() {
624 return mAction;
625 }
626
627 /**
Romain Guycafdea62009-06-12 10:51:36 -0700628 * Returns the time (in ms) when the user originally pressed down to start
629 * a stream of position events.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 */
631 public final long getDownTime() {
632 return mDownTime;
633 }
634
635 /**
636 * Returns the time (in ms) when this specific event was generated.
637 */
638 public final long getEventTime() {
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700639 return mTimeSamples[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640 }
641
642 /**
Michael Chan53071d62009-05-13 17:29:48 -0700643 * Returns the time (in ns) when this specific event was generated.
644 * The value is in nanosecond precision but it may not have nanosecond accuracy.
645 *
646 * @hide
647 */
648 public final long getEventTimeNano() {
649 return mEventTimeNano;
650 }
651
652 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700653 * {@link #getX(int)} for the first pointer index (may be an
654 * arbitrary pointer identifier).
655 */
656 public final float getX() {
657 return mDataSamples[SAMPLE_X];
658 }
659
660 /**
661 * {@link #getY(int)} for the first pointer index (may be an
662 * arbitrary pointer identifier).
663 */
664 public final float getY() {
665 return mDataSamples[SAMPLE_Y];
666 }
667
668 /**
669 * {@link #getPressure(int)} for the first pointer index (may be an
670 * arbitrary pointer identifier).
671 */
672 public final float getPressure() {
673 return mDataSamples[SAMPLE_PRESSURE];
674 }
675
676 /**
677 * {@link #getSize(int)} for the first pointer index (may be an
678 * arbitrary pointer identifier).
679 */
680 public final float getSize() {
681 return mDataSamples[SAMPLE_SIZE];
682 }
683
684 /**
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700685 * The number of pointers of data contained in this event. Always
686 * >= 1.
687 */
688 public final int getPointerCount() {
689 return mNumPointers;
690 }
691
692 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700693 * Return the pointer identifier associated with a particular pointer
694 * data index is this event. The identifier tells you the actual pointer
695 * number associated with the data, accounting for individual pointers
696 * going up and down since the start of the current gesture.
697 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
698 * (the first pointer that is down) to {@link #getPointerCount()}-1.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800699 */
Dianne Hackbornd41ba662009-08-05 15:30:56 -0700700 public final int getPointerId(int pointerIndex) {
701 return mPointerIdentifiers[pointerIndex];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800702 }
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700705 * Given a pointer identifier, find the index of its data in the event.
706 *
707 * @param pointerId The identifier of the pointer to be found.
708 * @return Returns either the index of the pointer (for use with
709 * {@link #getX(int) et al.), or -1 if there is no data available for
710 * that pointer identifier.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800711 */
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700712 public final int findPointerIndex(int pointerId) {
713 int i = mNumPointers;
714 while (i > 0) {
715 i--;
716 if (mPointerIdentifiers[i] == pointerId) {
717 return i;
718 }
719 }
720 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800721 }
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700724 * Returns the X coordinate of this event for the given pointer
725 * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
726 * identifier for this index).
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700727 * Whole numbers are pixels; the
728 * value may have a fraction for input devices that are sub-pixel precise.
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700729 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
730 * (the first pointer that is down) to {@link #getPointerCount()}-1.
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700731 */
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700732 public final float getX(int pointerIndex) {
733 return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_X];
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700734 }
735
736 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700737 * Returns the Y coordinate of this event for the given pointer
738 * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
739 * identifier for this index).
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700740 * Whole numbers are pixels; the
741 * value may have a fraction for input devices that are sub-pixel precise.
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700742 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
743 * (the first pointer that is down) to {@link #getPointerCount()}-1.
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700744 */
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700745 public final float getY(int pointerIndex) {
746 return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_Y];
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700747 }
748
749 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700750 * Returns the current pressure of this event for the given pointer
751 * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
752 * identifier for this index).
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700753 * The pressure generally
Romain Guycafdea62009-06-12 10:51:36 -0700754 * ranges from 0 (no pressure at all) to 1 (normal pressure), however
755 * values higher than 1 may be generated depending on the calibration of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 * the input device.
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700757 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
758 * (the first pointer that is down) to {@link #getPointerCount()}-1.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800759 */
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700760 public final float getPressure(int pointerIndex) {
761 return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_PRESSURE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 }
763
764 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700765 * Returns a scaled value of the approximate size for the given pointer
766 * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
767 * identifier for this index).
768 * This represents some approximation of the area of the screen being
769 * pressed; the actual value in pixels corresponding to the
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700770 * touch is normalized with the device specific range of values
Romain Guycafdea62009-06-12 10:51:36 -0700771 * and scaled to a value between 0 and 1. The value of size can be used to
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772 * determine fat touch events.
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700773 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
774 * (the first pointer that is down) to {@link #getPointerCount()}-1.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 */
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700776 public final float getSize(int pointerIndex) {
777 return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_SIZE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 }
779
780 /**
781 * Returns the state of any meta / modifier keys that were in effect when
782 * the event was generated. This is the same values as those
783 * returned by {@link KeyEvent#getMetaState() KeyEvent.getMetaState}.
784 *
785 * @return an integer in which each bit set to 1 represents a pressed
786 * meta key
787 *
788 * @see KeyEvent#getMetaState()
789 */
790 public final int getMetaState() {
791 return mMetaState;
792 }
793
794 /**
795 * Returns the original raw X coordinate of this event. For touch
796 * events on the screen, this is the original location of the event
797 * on the screen, before it had been adjusted for the containing window
798 * and views.
799 */
800 public final float getRawX() {
801 return mRawX;
802 }
803
804 /**
805 * Returns the original raw Y coordinate of this event. For touch
806 * events on the screen, this is the original location of the event
807 * on the screen, before it had been adjusted for the containing window
808 * and views.
809 */
810 public final float getRawY() {
811 return mRawY;
812 }
813
814 /**
815 * Return the precision of the X coordinates being reported. You can
816 * multiple this number with {@link #getX} to find the actual hardware
817 * value of the X coordinate.
818 * @return Returns the precision of X coordinates being reported.
819 */
820 public final float getXPrecision() {
821 return mXPrecision;
822 }
Romain Guycafdea62009-06-12 10:51:36 -0700823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 /**
825 * Return the precision of the Y coordinates being reported. You can
826 * multiple this number with {@link #getY} to find the actual hardware
827 * value of the Y coordinate.
828 * @return Returns the precision of Y coordinates being reported.
829 */
830 public final float getYPrecision() {
831 return mYPrecision;
832 }
Romain Guycafdea62009-06-12 10:51:36 -0700833
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 /**
835 * Returns the number of historical points in this event. These are
836 * movements that have occurred between this event and the previous event.
837 * This only applies to ACTION_MOVE events -- all other actions will have
838 * a size of 0.
Romain Guycafdea62009-06-12 10:51:36 -0700839 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840 * @return Returns the number of historical points in the event.
841 */
842 public final int getHistorySize() {
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700843 return mNumSamples - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800844 }
Romain Guycafdea62009-06-12 10:51:36 -0700845
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846 /**
847 * Returns the time that a historical movement occurred between this event
848 * and the previous event. Only applies to ACTION_MOVE events.
Romain Guycafdea62009-06-12 10:51:36 -0700849 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 * @param pos Which historical value to return; must be less than
851 * {@link #getHistorySize}
Romain Guycafdea62009-06-12 10:51:36 -0700852 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 * @see #getHistorySize
854 * @see #getEventTime
855 */
856 public final long getHistoricalEventTime(int pos) {
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700857 return mTimeSamples[pos + 1];
858 }
859
860 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700861 * {@link #getHistoricalX(int)} for the first pointer index (may be an
862 * arbitrary pointer identifier).
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700863 */
864 public final float getHistoricalX(int pos) {
865 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_X];
866 }
867
868 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700869 * {@link #getHistoricalY(int)} for the first pointer index (may be an
870 * arbitrary pointer identifier).
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700871 */
872 public final float getHistoricalY(int pos) {
873 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_Y];
874 }
875
876 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700877 * {@link #getHistoricalPressure(int)} for the first pointer index (may be an
878 * arbitrary pointer identifier).
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700879 */
880 public final float getHistoricalPressure(int pos) {
881 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_PRESSURE];
882 }
883
884 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700885 * {@link #getHistoricalSize(int)} for the first pointer index (may be an
886 * arbitrary pointer identifier).
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700887 */
888 public final float getHistoricalSize(int pos) {
889 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_SIZE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890 }
Romain Guycafdea62009-06-12 10:51:36 -0700891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800892 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700893 * Returns a historical X coordinate, as per {@link #getX(int)}, that
894 * occurred between this event and the previous event for the given pointer.
895 * Only applies to ACTION_MOVE events.
Romain Guycafdea62009-06-12 10:51:36 -0700896 *
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700897 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
898 * (the first pointer that is down) to {@link #getPointerCount()}-1.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899 * @param pos Which historical value to return; must be less than
900 * {@link #getHistorySize}
Romain Guycafdea62009-06-12 10:51:36 -0700901 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800902 * @see #getHistorySize
903 * @see #getX
904 */
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700905 public final float getHistoricalX(int pointerIndex, int pos) {
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700906 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers)
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700907 + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_X];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800908 }
Romain Guycafdea62009-06-12 10:51:36 -0700909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700911 * Returns a historical Y coordinate, as per {@link #getY(int)}, that
912 * occurred between this event and the previous event for the given pointer.
913 * Only applies to ACTION_MOVE events.
Romain Guycafdea62009-06-12 10:51:36 -0700914 *
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700915 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
916 * (the first pointer that is down) to {@link #getPointerCount()}-1.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 * @param pos Which historical value to return; must be less than
918 * {@link #getHistorySize}
Romain Guycafdea62009-06-12 10:51:36 -0700919 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920 * @see #getHistorySize
921 * @see #getY
922 */
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700923 public final float getHistoricalY(int pointerIndex, int pos) {
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700924 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers)
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700925 + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_Y];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 }
Romain Guycafdea62009-06-12 10:51:36 -0700927
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700929 * Returns a historical pressure coordinate, as per {@link #getPressure(int)},
930 * that occurred between this event and the previous event for the given
931 * pointer. Only applies to ACTION_MOVE events.
Romain Guycafdea62009-06-12 10:51:36 -0700932 *
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700933 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
934 * (the first pointer that is down) to {@link #getPointerCount()}-1.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 * @param pos Which historical value to return; must be less than
936 * {@link #getHistorySize}
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700937 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 * @see #getHistorySize
939 * @see #getPressure
940 */
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700941 public final float getHistoricalPressure(int pointerIndex, int pos) {
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700942 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers)
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700943 + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_PRESSURE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 }
Romain Guycafdea62009-06-12 10:51:36 -0700945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 /**
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700947 * Returns a historical size coordinate, as per {@link #getSize(int)}, that
948 * occurred between this event and the previous event for the given pointer.
949 * Only applies to ACTION_MOVE events.
Romain Guycafdea62009-06-12 10:51:36 -0700950 *
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700951 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
952 * (the first pointer that is down) to {@link #getPointerCount()}-1.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 * @param pos Which historical value to return; must be less than
954 * {@link #getHistorySize}
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700955 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800956 * @see #getHistorySize
957 * @see #getSize
958 */
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700959 public final float getHistoricalSize(int pointerIndex, int pos) {
Dianne Hackborn9822d2b2009-07-20 17:33:15 -0700960 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers)
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -0700961 + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_SIZE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800962 }
Romain Guycafdea62009-06-12 10:51:36 -0700963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 /**
965 * Return the id for the device that this event came from. An id of
966 * zero indicates that the event didn't come from a physical device; other
967 * numbers are arbitrary and you shouldn't depend on the values.
968 */
969 public final int getDeviceId() {
970 return mDeviceId;
971 }
Romain Guycafdea62009-06-12 10:51:36 -0700972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 /**
974 * Returns a bitfield indicating which edges, if any, where touched by this
Romain Guycafdea62009-06-12 10:51:36 -0700975 * MotionEvent. For touch events, clients can use this to determine if the
976 * user's finger was touching the edge of the display.
977 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 * @see #EDGE_LEFT
979 * @see #EDGE_TOP
980 * @see #EDGE_RIGHT
981 * @see #EDGE_BOTTOM
982 */
983 public final int getEdgeFlags() {
984 return mEdgeFlags;
985 }
Romain Guycafdea62009-06-12 10:51:36 -0700986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987
988 /**
989 * Sets the bitfield indicating which edges, if any, where touched by this
Romain Guycafdea62009-06-12 10:51:36 -0700990 * MotionEvent.
991 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 * @see #getEdgeFlags()
993 */
994 public final void setEdgeFlags(int flags) {
995 mEdgeFlags = flags;
996 }
997
998 /**
999 * Sets this event's action.
1000 */
1001 public final void setAction(int action) {
1002 mAction = action;
1003 }
1004
1005 /**
1006 * Adjust this event's location.
1007 * @param deltaX Amount to add to the current X coordinate of the event.
1008 * @param deltaY Amount to add to the current Y coordinate of the event.
1009 */
1010 public final void offsetLocation(float deltaX, float deltaY) {
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001011 final int N = mNumPointers*mNumSamples*4;
1012 final float[] pos = mDataSamples;
1013 for (int i=0; i<N; i+=NUM_SAMPLE_DATA) {
1014 pos[i+SAMPLE_X] += deltaX;
1015 pos[i+SAMPLE_Y] += deltaY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 }
1017 }
Romain Guycafdea62009-06-12 10:51:36 -07001018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 /**
1020 * Set this event's location. Applies {@link #offsetLocation} with a
1021 * delta from the current location to the given new location.
Romain Guycafdea62009-06-12 10:51:36 -07001022 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 * @param x New absolute X location.
1024 * @param y New absolute Y location.
1025 */
1026 public final void setLocation(float x, float y) {
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001027 float deltaX = x-mDataSamples[SAMPLE_X];
1028 float deltaY = y-mDataSamples[SAMPLE_Y];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001029 if (deltaX != 0 || deltaY != 0) {
1030 offsetLocation(deltaX, deltaY);
1031 }
1032 }
Romain Guycafdea62009-06-12 10:51:36 -07001033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001034 /**
1035 * Add a new movement to the batch of movements in this event. The event's
1036 * current location, position and size is updated to the new values. In
1037 * the future, the current values in the event will be added to a list of
1038 * historic values.
Romain Guycafdea62009-06-12 10:51:36 -07001039 *
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001040 * @param eventTime The time stamp for this data.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001041 * @param x The new X position.
1042 * @param y The new Y position.
1043 * @param pressure The new pressure.
1044 * @param size The new size.
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001045 * @param metaState Meta key state.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001046 */
1047 public final void addBatch(long eventTime, float x, float y,
1048 float pressure, float size, int metaState) {
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001049 float[] data = mDataSamples;
1050 long[] times = mTimeSamples;
1051
1052 final int NP = mNumPointers;
1053 final int NS = mNumSamples;
1054 final int NI = NP*NS;
1055 final int ND = NI * NUM_SAMPLE_DATA;
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -07001056 if (data.length <= ND) {
1057 final int NEW_ND = ND + (NP * (BASE_AVAIL_SAMPLES * NUM_SAMPLE_DATA));
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001058 float[] newData = new float[NEW_ND];
1059 System.arraycopy(data, 0, newData, 0, ND);
1060 mDataSamples = data = newData;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061 }
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001062 if (times.length <= NS) {
1063 final int NEW_NS = NS + BASE_AVAIL_SAMPLES;
1064 long[] newHistoryTimes = new long[NEW_NS];
1065 System.arraycopy(times, 0, newHistoryTimes, 0, NS);
1066 mTimeSamples = times = newHistoryTimes;
1067 }
1068
1069 times[NS] = times[0];
1070 times[0] = eventTime;
1071
1072 final int pos = NS*NUM_SAMPLE_DATA;
1073 data[pos+SAMPLE_X] = data[SAMPLE_X];
1074 data[pos+SAMPLE_Y] = data[SAMPLE_Y];
1075 data[pos+SAMPLE_PRESSURE] = data[SAMPLE_PRESSURE];
1076 data[pos+SAMPLE_SIZE] = data[SAMPLE_SIZE];
1077 data[SAMPLE_X] = x;
1078 data[SAMPLE_Y] = y;
1079 data[SAMPLE_PRESSURE] = pressure;
1080 data[SAMPLE_SIZE] = size;
1081 mNumSamples = NS+1;
Romain Guycafdea62009-06-12 10:51:36 -07001082
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001083 mRawX = x;
1084 mRawY = y;
1085 mMetaState |= metaState;
1086 }
Romain Guycafdea62009-06-12 10:51:36 -07001087
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001088 /**
1089 * Add a new movement to the batch of movements in this event. The
1090 * input data must contain (NUM_SAMPLE_DATA * {@link #getPointerCount()})
1091 * samples of data.
1092 *
1093 * @param eventTime The time stamp for this data.
1094 * @param inData The actual data.
1095 * @param metaState Meta key state.
1096 *
1097 * @hide
1098 */
1099 public final void addBatch(long eventTime, float[] inData, int metaState) {
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001100 float[] data = mDataSamples;
1101 long[] times = mTimeSamples;
1102
1103 final int NP = mNumPointers;
1104 final int NS = mNumSamples;
1105 final int NI = NP*NS;
1106 final int ND = NI * NUM_SAMPLE_DATA;
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -07001107 if (data.length <= ND) {
1108 final int NEW_ND = ND + (NP * (BASE_AVAIL_SAMPLES * NUM_SAMPLE_DATA));
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001109 float[] newData = new float[NEW_ND];
1110 System.arraycopy(data, 0, newData, 0, ND);
1111 mDataSamples = data = newData;
1112 }
1113 if (times.length <= NS) {
1114 final int NEW_NS = NS + BASE_AVAIL_SAMPLES;
1115 long[] newHistoryTimes = new long[NEW_NS];
1116 System.arraycopy(times, 0, newHistoryTimes, 0, NS);
1117 mTimeSamples = times = newHistoryTimes;
1118 }
1119
1120 times[NS] = times[0];
1121 times[0] = eventTime;
1122
1123 System.arraycopy(data, 0, data, ND, mNumPointers*NUM_SAMPLE_DATA);
1124 System.arraycopy(inData, 0, data, 0, mNumPointers*NUM_SAMPLE_DATA);
1125
1126 mNumSamples = NS+1;
Romain Guycafdea62009-06-12 10:51:36 -07001127
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001128 mRawX = inData[SAMPLE_X];
1129 mRawY = inData[SAMPLE_Y];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001130 mMetaState |= metaState;
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -07001131
1132 if (DEBUG_POINTERS) {
1133 StringBuilder sb = new StringBuilder(128);
1134 sb.append("Add:");
1135 for (int i=0; i<mNumPointers; i++) {
1136 sb.append(" #");
1137 sb.append(mPointerIdentifiers[i]);
1138 sb.append("(");
1139 sb.append(mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_X]);
1140 sb.append(",");
1141 sb.append(mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_Y]);
1142 sb.append(")");
1143 }
1144 Log.v("MotionEvent", sb.toString());
1145 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001146 }
Romain Guycafdea62009-06-12 10:51:36 -07001147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001148 @Override
1149 public String toString() {
1150 return "MotionEvent{" + Integer.toHexString(System.identityHashCode(this))
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001151 + " action=" + mAction + " x=" + getX()
1152 + " y=" + getY() + " pressure=" + getPressure() + " size=" + getSize() + "}";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001153 }
1154
1155 public static final Parcelable.Creator<MotionEvent> CREATOR
1156 = new Parcelable.Creator<MotionEvent>() {
1157 public MotionEvent createFromParcel(Parcel in) {
1158 MotionEvent ev = obtain();
1159 ev.readFromParcel(in);
1160 return ev;
1161 }
1162
1163 public MotionEvent[] newArray(int size) {
1164 return new MotionEvent[size];
1165 }
1166 };
1167
1168 public int describeContents() {
1169 return 0;
1170 }
1171
1172 public void writeToParcel(Parcel out, int flags) {
1173 out.writeLong(mDownTime);
Michael Chan53071d62009-05-13 17:29:48 -07001174 out.writeLong(mEventTimeNano);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 out.writeInt(mAction);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176 out.writeInt(mMetaState);
1177 out.writeFloat(mRawX);
1178 out.writeFloat(mRawY);
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001179 final int NP = mNumPointers;
1180 out.writeInt(NP);
1181 final int NS = mNumSamples;
1182 out.writeInt(NS);
1183 final int NI = NP*NS;
1184 if (NI > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001185 int i;
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -07001186 int[] state = mPointerIdentifiers;
1187 for (i=0; i<NP; i++) {
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001188 out.writeInt(state[i]);
1189 }
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -07001190 final int ND = NI*NUM_SAMPLE_DATA;
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001191 float[] history = mDataSamples;
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -07001192 for (i=0; i<ND; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001193 out.writeFloat(history[i]);
1194 }
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001195 long[] times = mTimeSamples;
1196 for (i=0; i<NS; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001197 out.writeLong(times[i]);
1198 }
1199 }
1200 out.writeFloat(mXPrecision);
1201 out.writeFloat(mYPrecision);
1202 out.writeInt(mDeviceId);
1203 out.writeInt(mEdgeFlags);
1204 }
1205
1206 private void readFromParcel(Parcel in) {
1207 mDownTime = in.readLong();
Michael Chan53071d62009-05-13 17:29:48 -07001208 mEventTimeNano = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001209 mAction = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 mMetaState = in.readInt();
1211 mRawX = in.readFloat();
1212 mRawY = in.readFloat();
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001213 final int NP = in.readInt();
1214 mNumPointers = NP;
1215 final int NS = in.readInt();
1216 mNumSamples = NS;
1217 final int NI = NP*NS;
1218 if (NI > 0) {
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -07001219 int[] ids = mPointerIdentifiers;
1220 if (ids.length < NP) {
1221 mPointerIdentifiers = ids = new int[NP];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 }
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -07001223 for (int i=0; i<NP; i++) {
1224 ids[i] = in.readInt();
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001225 }
1226 float[] history = mDataSamples;
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -07001227 final int ND = NI*NUM_SAMPLE_DATA;
1228 if (history.length < ND) {
1229 mDataSamples = history = new float[ND];
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001230 }
Dianne Hackborn0dd7cb42009-08-04 05:49:43 -07001231 for (int i=0; i<ND; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 history[i] = in.readFloat();
1233 }
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001234 long[] times = mTimeSamples;
1235 if (times == null || times.length < NS) {
1236 mTimeSamples = times = new long[NS];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 }
Dianne Hackborn9822d2b2009-07-20 17:33:15 -07001238 for (int i=0; i<NS; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001239 times[i] = in.readLong();
1240 }
1241 }
1242 mXPrecision = in.readFloat();
1243 mYPrecision = in.readFloat();
1244 mDeviceId = in.readInt();
1245 mEdgeFlags = in.readInt();
1246 }
1247
1248}