MotionEvent.java revision 5c225b1680e696ae8bbf505a1997d6f720672f74
1/*
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;
22import android.util.Log;
23
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 {
30    private static final long MS_PER_NS = 1000000;
31    static final boolean DEBUG_POINTERS = false;
32
33    /**
34     * Bit mask of the parts of the action code that are the action itself.
35     */
36    public static final int ACTION_MASK             = 0xff;
37
38    /**
39     * Constant for {@link #getAction}: A pressed gesture has started, the
40     * motion contains the initial starting location.
41     */
42    public static final int ACTION_DOWN             = 0;
43
44    /**
45     * Constant for {@link #getAction}: A pressed gesture has finished, the
46     * motion contains the final release location as well as any intermediate
47     * points since the last down or move event.
48     */
49    public static final int ACTION_UP               = 1;
50
51    /**
52     * Constant for {@link #getAction}: A change has happened during a
53     * press gesture (between {@link #ACTION_DOWN} and {@link #ACTION_UP}).
54     * The motion contains the most recent point, as well as any intermediate
55     * points since the last down or move event.
56     */
57    public static final int ACTION_MOVE             = 2;
58
59    /**
60     * Constant for {@link #getAction}: The current gesture has been aborted.
61     * You will not receive any more points in it.  You should treat this as
62     * an up event, but not perform any action that you normally would.
63     */
64    public static final int ACTION_CANCEL           = 3;
65
66    /**
67     * Constant for {@link #getAction}: A movement has happened outside of the
68     * normal bounds of the UI element.  This does not provide a full gesture,
69     * but only the initial location of the movement/touch.
70     */
71    public static final int ACTION_OUTSIDE          = 4;
72
73    /**
74     * A non-primary pointer has gone down.  The bits in
75     * {@link #ACTION_POINTER_ID_MASK} indicate which pointer changed.
76     */
77    public static final int ACTION_POINTER_DOWN     = 5;
78
79    /**
80     * A non-primary pointer has gone up.  The bits in
81     * {@link #ACTION_POINTER_ID_MASK} indicate which pointer changed.
82     */
83    public static final int ACTION_POINTER_UP       = 6;
84
85    /**
86     * Bits in the action code that represent a pointer index, used with
87     * {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}.  Shifting
88     * down by {@link #ACTION_POINTER_INDEX_SHIFT} provides the actual pointer
89     * index where the data for the pointer going up or down can be found; you can
90     * get its identifier with {@link #getPointerId(int)} and the actual
91     * data with {@link #getX(int)} etc.
92     */
93    public static final int ACTION_POINTER_INDEX_MASK  = 0xff00;
94
95    /**
96     * Bit shift for the action bits holding the pointer index as
97     * defined by {@link #ACTION_POINTER_INDEX_MASK}.
98     */
99    public static final int ACTION_POINTER_INDEX_SHIFT = 8;
100
101    /**
102     * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
103     * data index associated with {@link #ACTION_POINTER_DOWN}.
104     */
105    @Deprecated
106    public static final int ACTION_POINTER_1_DOWN   = ACTION_POINTER_DOWN | 0x0000;
107
108    /**
109     * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
110     * data index associated with {@link #ACTION_POINTER_DOWN}.
111     */
112    @Deprecated
113    public static final int ACTION_POINTER_2_DOWN   = ACTION_POINTER_DOWN | 0x0100;
114
115    /**
116     * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
117     * data index associated with {@link #ACTION_POINTER_DOWN}.
118     */
119    @Deprecated
120    public static final int ACTION_POINTER_3_DOWN   = ACTION_POINTER_DOWN | 0x0200;
121
122    /**
123     * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
124     * data index associated with {@link #ACTION_POINTER_UP}.
125     */
126    @Deprecated
127    public static final int ACTION_POINTER_1_UP     = ACTION_POINTER_UP | 0x0000;
128
129    /**
130     * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
131     * data index associated with {@link #ACTION_POINTER_UP}.
132     */
133    @Deprecated
134    public static final int ACTION_POINTER_2_UP     = ACTION_POINTER_UP | 0x0100;
135
136    /**
137     * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
138     * data index associated with {@link #ACTION_POINTER_UP}.
139     */
140    @Deprecated
141    public static final int ACTION_POINTER_3_UP     = ACTION_POINTER_UP | 0x0200;
142
143    /**
144     * @deprecated Renamed to {@link #ACTION_POINTER_INDEX_MASK} to match
145     * the actual data contained in these bits.
146     */
147    @Deprecated
148    public static final int ACTION_POINTER_ID_MASK  = 0xff00;
149
150    /**
151     * @deprecated Renamed to {@link #ACTION_POINTER_INDEX_SHIFT} to match
152     * the actual data contained in these bits.
153     */
154    @Deprecated
155    public static final int ACTION_POINTER_ID_SHIFT = 8;
156
157    private static final boolean TRACK_RECYCLED_LOCATION = false;
158
159    /**
160     * Flag indicating the motion event intersected the top edge of the screen.
161     */
162    public static final int EDGE_TOP = 0x00000001;
163
164    /**
165     * Flag indicating the motion event intersected the bottom edge of the screen.
166     */
167    public static final int EDGE_BOTTOM = 0x00000002;
168
169    /**
170     * Flag indicating the motion event intersected the left edge of the screen.
171     */
172    public static final int EDGE_LEFT = 0x00000004;
173
174    /**
175     * Flag indicating the motion event intersected the right edge of the screen.
176     */
177    public static final int EDGE_RIGHT = 0x00000008;
178
179    /**
180     * Offset for the sample's X coordinate.
181     * @hide
182     */
183    static public final int SAMPLE_X = 0;
184
185    /**
186     * Offset for the sample's Y coordinate.
187     * @hide
188     */
189    static public final int SAMPLE_Y = 1;
190
191    /**
192     * Offset for the sample's X coordinate.
193     * @hide
194     */
195    static public final int SAMPLE_PRESSURE = 2;
196
197    /**
198     * Offset for the sample's X coordinate.
199     * @hide
200     */
201    static public final int SAMPLE_SIZE = 3;
202
203    /**
204     * Number of data items for each sample.
205     * @hide
206     */
207    static public final int NUM_SAMPLE_DATA = 4;
208
209    /**
210     * Number of possible pointers.
211     * @hide
212     */
213    static public final int BASE_AVAIL_POINTERS = 5;
214
215    static private final int BASE_AVAIL_SAMPLES = 8;
216
217    static private final int MAX_RECYCLED = 10;
218    static private Object gRecyclerLock = new Object();
219    static private int gRecyclerUsed = 0;
220    static private MotionEvent gRecyclerTop = null;
221
222    private long mDownTimeNano;
223    private int mAction;
224    private float mXOffset;
225    private float mYOffset;
226    private float mXPrecision;
227    private float mYPrecision;
228    private int mDeviceId;
229    private int mEdgeFlags;
230    private int mMetaState;
231
232    private int mNumPointers;
233    private int mNumSamples;
234
235    private int mLastDataSampleIndex;
236    private int mLastEventTimeNanoSampleIndex;
237
238    // Array of mNumPointers size of identifiers for each pointer of data.
239    private int[] mPointerIdentifiers;
240
241    // Array of (mNumSamples * mNumPointers * NUM_SAMPLE_DATA) size of event data.
242    // Samples are ordered from oldest to newest.
243    private float[] mDataSamples;
244
245    // Array of mNumSamples size of event time stamps in nanoseconds.
246    // Samples are ordered from oldest to newest.
247    private long[] mEventTimeNanoSamples;
248
249    private MotionEvent mNext;
250    private RuntimeException mRecycledLocation;
251    private boolean mRecycled;
252
253    private MotionEvent(int pointerCount, int sampleCount) {
254        mPointerIdentifiers = new int[pointerCount];
255        mDataSamples = new float[pointerCount * sampleCount * NUM_SAMPLE_DATA];
256        mEventTimeNanoSamples = new long[sampleCount];
257    }
258
259    static private MotionEvent obtain(int pointerCount, int sampleCount) {
260        final MotionEvent ev;
261        synchronized (gRecyclerLock) {
262            if (gRecyclerTop == null) {
263                if (pointerCount < BASE_AVAIL_POINTERS) {
264                    pointerCount = BASE_AVAIL_POINTERS;
265                }
266                if (sampleCount < BASE_AVAIL_SAMPLES) {
267                    sampleCount = BASE_AVAIL_SAMPLES;
268                }
269                return new MotionEvent(pointerCount, sampleCount);
270            }
271            ev = gRecyclerTop;
272            gRecyclerTop = ev.mNext;
273            gRecyclerUsed -= 1;
274        }
275        ev.mRecycledLocation = null;
276        ev.mRecycled = false;
277        ev.mNext = null;
278
279        if (ev.mPointerIdentifiers.length < pointerCount) {
280            ev.mPointerIdentifiers = new int[pointerCount];
281        }
282
283        if (ev.mEventTimeNanoSamples.length < sampleCount) {
284            ev.mEventTimeNanoSamples = new long[sampleCount];
285        }
286
287        final int neededDataSamplesLength = pointerCount * sampleCount * NUM_SAMPLE_DATA;
288        if (ev.mDataSamples.length < neededDataSamplesLength) {
289            ev.mDataSamples = new float[neededDataSamplesLength];
290        }
291
292        return ev;
293    }
294
295    /**
296     * Create a new MotionEvent, filling in all of the basic values that
297     * define the motion.
298     *
299     * @param downTime The time (in ms) when the user originally pressed down to start
300     * a stream of position events.  This must be obtained from {@link SystemClock#uptimeMillis()}.
301     * @param eventTime  The the time (in ms) when this specific event was generated.  This
302     * must be obtained from {@link SystemClock#uptimeMillis()}.
303     * @param eventTimeNano  The the time (in ns) when this specific event was generated.  This
304     * must be obtained from {@link System#nanoTime()}.
305     * @param action The kind of action being performed -- one of either
306     * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
307     * {@link #ACTION_CANCEL}.
308     * @param pointers The number of points that will be in this event.
309     * @param inPointerIds An array of <em>pointers</em> values providing
310     * an identifier for each pointer.
311     * @param inData An array of <em>pointers*NUM_SAMPLE_DATA</em> of initial
312     * data samples for the event.
313     * @param metaState The state of any meta / modifier keys that were in effect when
314     * the event was generated.
315     * @param xPrecision The precision of the X coordinate being reported.
316     * @param yPrecision The precision of the Y coordinate being reported.
317     * @param deviceId The id for the device that this event came from.  An id of
318     * zero indicates that the event didn't come from a physical device; other
319     * numbers are arbitrary and you shouldn't depend on the values.
320     * @param edgeFlags A bitfield indicating which edges, if any, where touched by this
321     * MotionEvent.
322     *
323     * @hide
324     */
325    static public MotionEvent obtainNano(long downTime, long eventTime, long eventTimeNano,
326            int action, int pointers, int[] inPointerIds, float[] inData, int metaState,
327            float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
328        MotionEvent ev = obtain(pointers, 1);
329        ev.mDeviceId = deviceId;
330        ev.mEdgeFlags = edgeFlags;
331        ev.mDownTimeNano = downTime * MS_PER_NS;
332        ev.mAction = action;
333        ev.mMetaState = metaState;
334        ev.mXOffset = 0;
335        ev.mYOffset = 0;
336        ev.mXPrecision = xPrecision;
337        ev.mYPrecision = yPrecision;
338
339        ev.mNumPointers = pointers;
340        ev.mNumSamples = 1;
341
342        ev.mLastDataSampleIndex = 0;
343        ev.mLastEventTimeNanoSampleIndex = 0;
344
345        System.arraycopy(inPointerIds, 0, ev.mPointerIdentifiers, 0, pointers);
346
347        ev.mEventTimeNanoSamples[0] = eventTimeNano;
348
349        System.arraycopy(inData, 0, ev.mDataSamples, 0, pointers * NUM_SAMPLE_DATA);
350
351        if (DEBUG_POINTERS) {
352            StringBuilder sb = new StringBuilder(128);
353            sb.append("New:");
354            for (int i = 0; i < pointers; i++) {
355                sb.append(" #");
356                sb.append(ev.getPointerId(i));
357                sb.append("(");
358                sb.append(ev.getX(i));
359                sb.append(",");
360                sb.append(ev.getY(i));
361                sb.append(")");
362            }
363            Log.v("MotionEvent", sb.toString());
364        }
365
366        return ev;
367    }
368
369    /**
370     * Create a new MotionEvent, filling in all of the basic values that
371     * define the motion.
372     *
373     * @param downTime The time (in ms) when the user originally pressed down to start
374     * a stream of position events.  This must be obtained from {@link SystemClock#uptimeMillis()}.
375     * @param eventTime  The the time (in ms) when this specific event was generated.  This
376     * must be obtained from {@link SystemClock#uptimeMillis()}.
377     * @param action The kind of action being performed -- one of either
378     * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
379     * {@link #ACTION_CANCEL}.
380     * @param x The X coordinate of this event.
381     * @param y The Y coordinate of this event.
382     * @param pressure The current pressure of this event.  The pressure generally
383     * ranges from 0 (no pressure at all) to 1 (normal pressure), however
384     * values higher than 1 may be generated depending on the calibration of
385     * the input device.
386     * @param size A scaled value of the approximate size of the area being pressed when
387     * touched with the finger. The actual value in pixels corresponding to the finger
388     * touch is normalized with a device specific range of values
389     * and scaled to a value between 0 and 1.
390     * @param metaState The state of any meta / modifier keys that were in effect when
391     * the event was generated.
392     * @param xPrecision The precision of the X coordinate being reported.
393     * @param yPrecision The precision of the Y coordinate being reported.
394     * @param deviceId The id for the device that this event came from.  An id of
395     * zero indicates that the event didn't come from a physical device; other
396     * numbers are arbitrary and you shouldn't depend on the values.
397     * @param edgeFlags A bitfield indicating which edges, if any, where touched by this
398     * MotionEvent.
399     */
400    static public MotionEvent obtain(long downTime, long eventTime, int action,
401            float x, float y, float pressure, float size, int metaState,
402            float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
403        MotionEvent ev = obtain(1, 1);
404        ev.mDeviceId = deviceId;
405        ev.mEdgeFlags = edgeFlags;
406        ev.mDownTimeNano = downTime * MS_PER_NS;
407        ev.mAction = action;
408        ev.mMetaState = metaState;
409        ev.mXOffset = 0;
410        ev.mYOffset = 0;
411        ev.mXPrecision = xPrecision;
412        ev.mYPrecision = yPrecision;
413
414        ev.mNumPointers = 1;
415        ev.mNumSamples = 1;
416
417        ev.mLastDataSampleIndex = 0;
418        ev.mLastEventTimeNanoSampleIndex = 0;
419
420        ev.mPointerIdentifiers[0] = 0;
421
422        ev.mEventTimeNanoSamples[0] = eventTime * MS_PER_NS;
423
424        float[] dataSamples = ev.mDataSamples;
425        dataSamples[SAMPLE_X] = x;
426        dataSamples[SAMPLE_Y] = y;
427        dataSamples[SAMPLE_PRESSURE] = pressure;
428        dataSamples[SAMPLE_SIZE] = size;
429        return ev;
430    }
431
432    /**
433     * Create a new MotionEvent, filling in all of the basic values that
434     * define the motion.
435     *
436     * @param downTime The time (in ms) when the user originally pressed down to start
437     * a stream of position events.  This must be obtained from {@link SystemClock#uptimeMillis()}.
438     * @param eventTime  The the time (in ms) when this specific event was generated.  This
439     * must be obtained from {@link SystemClock#uptimeMillis()}.
440     * @param action The kind of action being performed -- one of either
441     * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
442     * {@link #ACTION_CANCEL}.
443     * @param pointers The number of pointers that are active in this event.
444     * @param x The X coordinate of this event.
445     * @param y The Y coordinate of this event.
446     * @param pressure The current pressure of this event.  The pressure generally
447     * ranges from 0 (no pressure at all) to 1 (normal pressure), however
448     * values higher than 1 may be generated depending on the calibration of
449     * the input device.
450     * @param size A scaled value of the approximate size of the area being pressed when
451     * touched with the finger. The actual value in pixels corresponding to the finger
452     * touch is normalized with a device specific range of values
453     * and scaled to a value between 0 and 1.
454     * @param metaState The state of any meta / modifier keys that were in effect when
455     * the event was generated.
456     * @param xPrecision The precision of the X coordinate being reported.
457     * @param yPrecision The precision of the Y coordinate being reported.
458     * @param deviceId The id for the device that this event came from.  An id of
459     * zero indicates that the event didn't come from a physical device; other
460     * numbers are arbitrary and you shouldn't depend on the values.
461     * @param edgeFlags A bitfield indicating which edges, if any, where touched by this
462     * MotionEvent.
463     *
464     * @deprecated Use {@link #obtain(long, long, int, float, float, float, float, int, float, float, int, int)}
465     * instead.
466     */
467    @Deprecated
468    static public MotionEvent obtain(long downTime, long eventTime, int action,
469            int pointers, float x, float y, float pressure, float size, int metaState,
470            float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
471        return obtain(downTime, eventTime, action, x, y, pressure, size,
472                metaState, xPrecision, yPrecision, deviceId, edgeFlags);
473    }
474
475    /**
476     * Create a new MotionEvent, filling in a subset of the basic motion
477     * values.  Those not specified here are: device id (always 0), pressure
478     * and size (always 1), x and y precision (always 1), and edgeFlags (always 0).
479     *
480     * @param downTime The time (in ms) when the user originally pressed down to start
481     * a stream of position events.  This must be obtained from {@link SystemClock#uptimeMillis()}.
482     * @param eventTime  The the time (in ms) when this specific event was generated.  This
483     * must be obtained from {@link SystemClock#uptimeMillis()}.
484     * @param action The kind of action being performed -- one of either
485     * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
486     * {@link #ACTION_CANCEL}.
487     * @param x The X coordinate of this event.
488     * @param y The Y coordinate of this event.
489     * @param metaState The state of any meta / modifier keys that were in effect when
490     * the event was generated.
491     */
492    static public MotionEvent obtain(long downTime, long eventTime, int action,
493            float x, float y, int metaState) {
494        return obtain(downTime, eventTime, action, x, y, 1.0f, 1.0f,
495                metaState, 1.0f, 1.0f, 0, 0);
496    }
497
498    /**
499     * Create a new MotionEvent, copying from an existing one.
500     */
501    static public MotionEvent obtain(MotionEvent o) {
502        MotionEvent ev = obtain(o.mNumPointers, o.mNumSamples);
503        ev.mDeviceId = o.mDeviceId;
504        ev.mEdgeFlags = o.mEdgeFlags;
505        ev.mDownTimeNano = o.mDownTimeNano;
506        ev.mAction = o.mAction;
507        ev.mMetaState = o.mMetaState;
508        ev.mXOffset = o.mXOffset;
509        ev.mYOffset = o.mYOffset;
510        ev.mXPrecision = o.mXPrecision;
511        ev.mYPrecision = o.mYPrecision;
512        int numPointers = ev.mNumPointers = o.mNumPointers;
513        int numSamples = ev.mNumSamples = o.mNumSamples;
514
515        ev.mLastDataSampleIndex = o.mLastDataSampleIndex;
516        ev.mLastEventTimeNanoSampleIndex = o.mLastEventTimeNanoSampleIndex;
517
518        System.arraycopy(o.mPointerIdentifiers, 0, ev.mPointerIdentifiers, 0, numPointers);
519
520        System.arraycopy(o.mEventTimeNanoSamples, 0, ev.mEventTimeNanoSamples, 0, numSamples);
521
522        System.arraycopy(o.mDataSamples, 0, ev.mDataSamples, 0,
523                numPointers * numSamples * NUM_SAMPLE_DATA);
524        return ev;
525    }
526
527    /**
528     * Create a new MotionEvent, copying from an existing one, but not including
529     * any historical point information.
530     */
531    static public MotionEvent obtainNoHistory(MotionEvent o) {
532        MotionEvent ev = obtain(o.mNumPointers, 1);
533        ev.mDeviceId = o.mDeviceId;
534        ev.mEdgeFlags = o.mEdgeFlags;
535        ev.mDownTimeNano = o.mDownTimeNano;
536        ev.mAction = o.mAction;
537        ev.mMetaState = o.mMetaState;
538        ev.mXOffset = o.mXOffset;
539        ev.mYOffset = o.mYOffset;
540        ev.mXPrecision = o.mXPrecision;
541        ev.mYPrecision = o.mYPrecision;
542
543        int numPointers = ev.mNumPointers = o.mNumPointers;
544        ev.mNumSamples = 1;
545
546        ev.mLastDataSampleIndex = 0;
547        ev.mLastEventTimeNanoSampleIndex = 0;
548
549        System.arraycopy(o.mPointerIdentifiers, 0, ev.mPointerIdentifiers, 0, numPointers);
550
551        ev.mEventTimeNanoSamples[0] = o.mEventTimeNanoSamples[o.mLastEventTimeNanoSampleIndex];
552
553        System.arraycopy(o.mDataSamples, o.mLastDataSampleIndex, ev.mDataSamples, 0,
554                numPointers * NUM_SAMPLE_DATA);
555        return ev;
556    }
557
558    /**
559     * Recycle the MotionEvent, to be re-used by a later caller.  After calling
560     * this function you must not ever touch the event again.
561     */
562    public final void recycle() {
563        // Ensure recycle is only called once!
564        if (TRACK_RECYCLED_LOCATION) {
565            if (mRecycledLocation != null) {
566                throw new RuntimeException(toString() + " recycled twice!", mRecycledLocation);
567            }
568            mRecycledLocation = new RuntimeException("Last recycled here");
569            //Log.w("MotionEvent", "Recycling event " + this, mRecycledLocation);
570        } else {
571            if (mRecycled) {
572                throw new RuntimeException(toString() + " recycled twice!");
573            }
574            mRecycled = true;
575        }
576
577        synchronized (gRecyclerLock) {
578            if (gRecyclerUsed < MAX_RECYCLED) {
579                gRecyclerUsed++;
580                mNumSamples = 0;
581                mNext = gRecyclerTop;
582                gRecyclerTop = this;
583            }
584        }
585    }
586
587    /**
588     * Scales down the coordination of this event by the given scale.
589     *
590     * @hide
591     */
592    public final void scale(float scale) {
593        mXOffset *= scale;
594        mYOffset *= scale;
595        mXPrecision *= scale;
596        mYPrecision *= scale;
597
598        float[] history = mDataSamples;
599        final int length = mNumPointers * mNumSamples * NUM_SAMPLE_DATA;
600        for (int i = 0; i < length; i += NUM_SAMPLE_DATA) {
601            history[i + SAMPLE_X] *= scale;
602            history[i + SAMPLE_Y] *= scale;
603            // no need to scale pressure
604            history[i + SAMPLE_SIZE] *= scale;    // TODO: square this?
605        }
606    }
607
608    /**
609     * Return the kind of action being performed -- one of either
610     * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
611     * {@link #ACTION_CANCEL}.  Consider using {@link #getActionMasked}
612     * and {@link #getActionIndex} to retrieve the separate masked action
613     * and pointer index.
614     */
615    public final int getAction() {
616        return mAction;
617    }
618
619    /**
620     * Return the masked action being performed, without pointer index
621     * information.  May be any of the actions: {@link #ACTION_DOWN},
622     * {@link #ACTION_MOVE}, {@link #ACTION_UP}, {@link #ACTION_CANCEL},
623     * {@link #ACTION_POINTER_DOWN}, or {@link #ACTION_POINTER_UP}.
624     * Use {@link #getActionIndex} to return the index associated with
625     * pointer actions.
626     */
627    public final int getActionMasked() {
628        return mAction & ACTION_MASK;
629    }
630
631    /**
632     * For {@link #ACTION_POINTER_DOWN} or {@link #ACTION_POINTER_UP}
633     * as returned by {@link #getActionMasked}, this returns the associated
634     * pointer index.  The index may be used with {@link #getPointerId(int)},
635     * {@link #getX(int)}, {@link #getY(int)}, {@link #getPressure(int)},
636     * and {@link #getSize(int)} to get information about the pointer that has
637     * gone down or up.
638     */
639    public final int getActionIndex() {
640        return (mAction & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT;
641    }
642
643    /**
644     * Returns the time (in ms) when the user originally pressed down to start
645     * a stream of position events.
646     */
647    public final long getDownTime() {
648        return mDownTimeNano / MS_PER_NS;
649    }
650
651    /**
652     * Returns the time (in ms) when this specific event was generated.
653     */
654    public final long getEventTime() {
655        return mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex] / MS_PER_NS;
656    }
657
658    /**
659     * Returns the time (in ns) when this specific event was generated.
660     * The value is in nanosecond precision but it may not have nanosecond accuracy.
661     *
662     * @hide
663     */
664    public final long getEventTimeNano() {
665        return mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex];
666    }
667
668    /**
669     * {@link #getX(int)} for the first pointer index (may be an
670     * arbitrary pointer identifier).
671     */
672    public final float getX() {
673        return mDataSamples[mLastDataSampleIndex + SAMPLE_X] + mXOffset;
674    }
675
676    /**
677     * {@link #getY(int)} for the first pointer index (may be an
678     * arbitrary pointer identifier).
679     */
680    public final float getY() {
681        return mDataSamples[mLastDataSampleIndex + SAMPLE_Y] + mYOffset;
682    }
683
684    /**
685     * {@link #getPressure(int)} for the first pointer index (may be an
686     * arbitrary pointer identifier).
687     */
688    public final float getPressure() {
689        return mDataSamples[mLastDataSampleIndex + SAMPLE_PRESSURE];
690    }
691
692    /**
693     * {@link #getSize(int)} for the first pointer index (may be an
694     * arbitrary pointer identifier).
695     */
696    public final float getSize() {
697        return mDataSamples[mLastDataSampleIndex + SAMPLE_SIZE];
698    }
699
700    /**
701     * The number of pointers of data contained in this event.  Always
702     * >= 1.
703     */
704    public final int getPointerCount() {
705        return mNumPointers;
706    }
707
708    /**
709     * Return the pointer identifier associated with a particular pointer
710     * data index is this event.  The identifier tells you the actual pointer
711     * number associated with the data, accounting for individual pointers
712     * going up and down since the start of the current gesture.
713     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
714     * (the first pointer that is down) to {@link #getPointerCount()}-1.
715     */
716    public final int getPointerId(int pointerIndex) {
717        return mPointerIdentifiers[pointerIndex];
718    }
719
720    /**
721     * Given a pointer identifier, find the index of its data in the event.
722     *
723     * @param pointerId The identifier of the pointer to be found.
724     * @return Returns either the index of the pointer (for use with
725     * {@link #getX(int) et al.), or -1 if there is no data available for
726     * that pointer identifier.
727     */
728    public final int findPointerIndex(int pointerId) {
729        int i = mNumPointers;
730        while (i > 0) {
731            i--;
732            if (mPointerIdentifiers[i] == pointerId) {
733                return i;
734            }
735        }
736        return -1;
737    }
738
739    /**
740     * Returns the X coordinate of this event for the given pointer
741     * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
742     * identifier for this index).
743     * Whole numbers are pixels; the
744     * value may have a fraction for input devices that are sub-pixel precise.
745     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
746     * (the first pointer that is down) to {@link #getPointerCount()}-1.
747     */
748    public final float getX(int pointerIndex) {
749        return mDataSamples[mLastDataSampleIndex
750                            + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_X] + mXOffset;
751    }
752
753    /**
754     * Returns the Y coordinate of this event for the given pointer
755     * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
756     * identifier for this index).
757     * Whole numbers are pixels; the
758     * value may have a fraction for input devices that are sub-pixel precise.
759     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
760     * (the first pointer that is down) to {@link #getPointerCount()}-1.
761     */
762    public final float getY(int pointerIndex) {
763        return mDataSamples[mLastDataSampleIndex
764                            + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_Y] + mYOffset;
765    }
766
767    /**
768     * Returns the current pressure of this event for the given pointer
769     * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
770     * identifier for this index).
771     * The pressure generally
772     * ranges from 0 (no pressure at all) to 1 (normal pressure), however
773     * values higher than 1 may be generated depending on the calibration of
774     * the input device.
775     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
776     * (the first pointer that is down) to {@link #getPointerCount()}-1.
777     */
778    public final float getPressure(int pointerIndex) {
779        return mDataSamples[mLastDataSampleIndex
780                            + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_PRESSURE];
781    }
782
783    /**
784     * Returns a scaled value of the approximate size for the given pointer
785     * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
786     * identifier for this index).
787     * This represents some approximation of the area of the screen being
788     * pressed; the actual value in pixels corresponding to the
789     * touch is normalized with the device specific range of values
790     * and scaled to a value between 0 and 1. The value of size can be used to
791     * determine fat touch events.
792     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
793     * (the first pointer that is down) to {@link #getPointerCount()}-1.
794     */
795    public final float getSize(int pointerIndex) {
796        return mDataSamples[mLastDataSampleIndex
797                            + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_SIZE];
798    }
799
800    /**
801     * Returns the state of any meta / modifier keys that were in effect when
802     * the event was generated.  This is the same values as those
803     * returned by {@link KeyEvent#getMetaState() KeyEvent.getMetaState}.
804     *
805     * @return an integer in which each bit set to 1 represents a pressed
806     *         meta key
807     *
808     * @see KeyEvent#getMetaState()
809     */
810    public final int getMetaState() {
811        return mMetaState;
812    }
813
814    /**
815     * Returns the original raw X coordinate of this event.  For touch
816     * events on the screen, this is the original location of the event
817     * on the screen, before it had been adjusted for the containing window
818     * and views.
819     */
820    public final float getRawX() {
821        return mDataSamples[mLastDataSampleIndex + SAMPLE_X];
822    }
823
824    /**
825     * Returns the original raw Y coordinate of this event.  For touch
826     * events on the screen, this is the original location of the event
827     * on the screen, before it had been adjusted for the containing window
828     * and views.
829     */
830    public final float getRawY() {
831        return mDataSamples[mLastDataSampleIndex + SAMPLE_Y];
832    }
833
834    /**
835     * Return the precision of the X coordinates being reported.  You can
836     * multiple this number with {@link #getX} to find the actual hardware
837     * value of the X coordinate.
838     * @return Returns the precision of X coordinates being reported.
839     */
840    public final float getXPrecision() {
841        return mXPrecision;
842    }
843
844    /**
845     * Return the precision of the Y coordinates being reported.  You can
846     * multiple this number with {@link #getY} to find the actual hardware
847     * value of the Y coordinate.
848     * @return Returns the precision of Y coordinates being reported.
849     */
850    public final float getYPrecision() {
851        return mYPrecision;
852    }
853
854    /**
855     * Returns the number of historical points in this event.  These are
856     * movements that have occurred between this event and the previous event.
857     * This only applies to ACTION_MOVE events -- all other actions will have
858     * a size of 0.
859     *
860     * @return Returns the number of historical points in the event.
861     */
862    public final int getHistorySize() {
863        return mLastEventTimeNanoSampleIndex;
864    }
865
866    /**
867     * Returns the time that a historical movement occurred between this event
868     * and the previous event.  Only applies to ACTION_MOVE events.
869     *
870     * @param pos Which historical value to return; must be less than
871     * {@link #getHistorySize}
872     *
873     * @see #getHistorySize
874     * @see #getEventTime
875     */
876    public final long getHistoricalEventTime(int pos) {
877        return mEventTimeNanoSamples[pos] / MS_PER_NS;
878    }
879
880    /**
881     * {@link #getHistoricalX(int)} for the first pointer index (may be an
882     * arbitrary pointer identifier).
883     */
884    public final float getHistoricalX(int pos) {
885        return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_X] + mXOffset;
886    }
887
888    /**
889     * {@link #getHistoricalY(int)} for the first pointer index (may be an
890     * arbitrary pointer identifier).
891     */
892    public final float getHistoricalY(int pos) {
893        return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_Y] + mYOffset;
894    }
895
896    /**
897     * {@link #getHistoricalPressure(int)} for the first pointer index (may be an
898     * arbitrary pointer identifier).
899     */
900    public final float getHistoricalPressure(int pos) {
901        return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_PRESSURE];
902    }
903
904    /**
905     * {@link #getHistoricalSize(int)} for the first pointer index (may be an
906     * arbitrary pointer identifier).
907     */
908    public final float getHistoricalSize(int pos) {
909        return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_SIZE];
910    }
911
912    /**
913     * Returns a historical X coordinate, as per {@link #getX(int)}, that
914     * occurred between this event and the previous event for the given pointer.
915     * Only applies to ACTION_MOVE events.
916     *
917     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
918     * (the first pointer that is down) to {@link #getPointerCount()}-1.
919     * @param pos Which historical value to return; must be less than
920     * {@link #getHistorySize}
921     *
922     * @see #getHistorySize
923     * @see #getX
924     */
925    public final float getHistoricalX(int pointerIndex, int pos) {
926        return mDataSamples[(pos * mNumPointers + pointerIndex)
927                            * NUM_SAMPLE_DATA + SAMPLE_X] + mXOffset;
928    }
929
930    /**
931     * Returns a historical Y coordinate, as per {@link #getY(int)}, that
932     * occurred between this event and the previous event for the given pointer.
933     * Only applies to ACTION_MOVE events.
934     *
935     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
936     * (the first pointer that is down) to {@link #getPointerCount()}-1.
937     * @param pos Which historical value to return; must be less than
938     * {@link #getHistorySize}
939     *
940     * @see #getHistorySize
941     * @see #getY
942     */
943    public final float getHistoricalY(int pointerIndex, int pos) {
944        return mDataSamples[(pos * mNumPointers + pointerIndex)
945                            * NUM_SAMPLE_DATA + SAMPLE_Y] + mYOffset;
946    }
947
948    /**
949     * Returns a historical pressure coordinate, as per {@link #getPressure(int)},
950     * that occurred between this event and the previous event for the given
951     * pointer.  Only applies to ACTION_MOVE events.
952     *
953     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
954     * (the first pointer that is down) to {@link #getPointerCount()}-1.
955     * @param pos Which historical value to return; must be less than
956     * {@link #getHistorySize}
957     *
958     * @see #getHistorySize
959     * @see #getPressure
960     */
961    public final float getHistoricalPressure(int pointerIndex, int pos) {
962        return mDataSamples[(pos * mNumPointers + pointerIndex)
963                            * NUM_SAMPLE_DATA + SAMPLE_PRESSURE];
964    }
965
966    /**
967     * Returns a historical size coordinate, as per {@link #getSize(int)}, that
968     * occurred between this event and the previous event for the given pointer.
969     * Only applies to ACTION_MOVE events.
970     *
971     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
972     * (the first pointer that is down) to {@link #getPointerCount()}-1.
973     * @param pos Which historical value to return; must be less than
974     * {@link #getHistorySize}
975     *
976     * @see #getHistorySize
977     * @see #getSize
978     */
979    public final float getHistoricalSize(int pointerIndex, int pos) {
980        return mDataSamples[(pos * mNumPointers + pointerIndex)
981                            * NUM_SAMPLE_DATA + SAMPLE_SIZE];
982    }
983
984    /**
985     * Return the id for the device that this event came from.  An id of
986     * zero indicates that the event didn't come from a physical device; other
987     * numbers are arbitrary and you shouldn't depend on the values.
988     */
989    public final int getDeviceId() {
990        return mDeviceId;
991    }
992
993    /**
994     * Returns a bitfield indicating which edges, if any, were touched by this
995     * MotionEvent. For touch events, clients can use this to determine if the
996     * user's finger was touching the edge of the display.
997     *
998     * @see #EDGE_LEFT
999     * @see #EDGE_TOP
1000     * @see #EDGE_RIGHT
1001     * @see #EDGE_BOTTOM
1002     */
1003    public final int getEdgeFlags() {
1004        return mEdgeFlags;
1005    }
1006
1007
1008    /**
1009     * Sets the bitfield indicating which edges, if any, where touched by this
1010     * MotionEvent.
1011     *
1012     * @see #getEdgeFlags()
1013     */
1014    public final void setEdgeFlags(int flags) {
1015        mEdgeFlags = flags;
1016    }
1017
1018    /**
1019     * Sets this event's action.
1020     */
1021    public final void setAction(int action) {
1022        mAction = action;
1023    }
1024
1025    /**
1026     * Adjust this event's location.
1027     * @param deltaX Amount to add to the current X coordinate of the event.
1028     * @param deltaY Amount to add to the current Y coordinate of the event.
1029     */
1030    public final void offsetLocation(float deltaX, float deltaY) {
1031        mXOffset += deltaX;
1032        mYOffset += deltaY;
1033    }
1034
1035    /**
1036     * Set this event's location.  Applies {@link #offsetLocation} with a
1037     * delta from the current location to the given new location.
1038     *
1039     * @param x New absolute X location.
1040     * @param y New absolute Y location.
1041     */
1042    public final void setLocation(float x, float y) {
1043        mXOffset = x - mDataSamples[mLastDataSampleIndex + SAMPLE_X];
1044        mYOffset = y - mDataSamples[mLastDataSampleIndex + SAMPLE_Y];
1045    }
1046
1047    private final void incrementNumSamplesAndReserveStorage(int dataSampleStride) {
1048        if (mNumSamples == mEventTimeNanoSamples.length) {
1049            long[] newEventTimeNanoSamples = new long[mNumSamples + BASE_AVAIL_SAMPLES];
1050            System.arraycopy(mEventTimeNanoSamples, 0, newEventTimeNanoSamples, 0, mNumSamples);
1051            mEventTimeNanoSamples = newEventTimeNanoSamples;
1052        }
1053
1054        int nextDataSampleIndex = mLastDataSampleIndex + dataSampleStride;
1055        if (nextDataSampleIndex + dataSampleStride > mDataSamples.length) {
1056            float[] newDataSamples = new float[nextDataSampleIndex
1057                                               + BASE_AVAIL_SAMPLES * dataSampleStride];
1058            System.arraycopy(mDataSamples, 0, newDataSamples, 0, nextDataSampleIndex);
1059            mDataSamples = newDataSamples;
1060        }
1061
1062        mLastEventTimeNanoSampleIndex = mNumSamples;
1063        mLastDataSampleIndex = nextDataSampleIndex;
1064        mNumSamples += 1;
1065    }
1066
1067    /**
1068     * Add a new movement to the batch of movements in this event.  The event's
1069     * current location, position and size is updated to the new values.  In
1070     * the future, the current values in the event will be added to a list of
1071     * historic values.
1072     *
1073     * @param eventTime The time stamp for this data.
1074     * @param x The new X position.
1075     * @param y The new Y position.
1076     * @param pressure The new pressure.
1077     * @param size The new size.
1078     * @param metaState Meta key state.
1079     */
1080    public final void addBatch(long eventTime, float x, float y,
1081            float pressure, float size, int metaState) {
1082        incrementNumSamplesAndReserveStorage(NUM_SAMPLE_DATA);
1083
1084        mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex] = eventTime * MS_PER_NS;
1085
1086        float[] dataSamples = mDataSamples;
1087        dataSamples[mLastDataSampleIndex + SAMPLE_X] = x - mXOffset;
1088        dataSamples[mLastDataSampleIndex + SAMPLE_Y] = y - mYOffset;
1089        dataSamples[mLastDataSampleIndex + SAMPLE_PRESSURE] = pressure;
1090        dataSamples[mLastDataSampleIndex + SAMPLE_SIZE] = size;
1091
1092        mMetaState |= metaState;
1093    }
1094
1095    /**
1096     * Add a new movement to the batch of movements in this event.  The
1097     * input data must contain (NUM_SAMPLE_DATA * {@link #getPointerCount()})
1098     * samples of data.
1099     *
1100     * @param eventTime The time stamp for this data.
1101     * @param inData The actual data.
1102     * @param metaState Meta key state.
1103     *
1104     * @hide
1105     */
1106    public final void addBatch(long eventTime, float[] inData, int metaState) {
1107        final int numPointers = mNumPointers;
1108        final int dataSampleStride = numPointers * NUM_SAMPLE_DATA;
1109        incrementNumSamplesAndReserveStorage(dataSampleStride);
1110
1111        mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex] = eventTime * MS_PER_NS;
1112
1113        float[] dataSamples = mDataSamples;
1114        System.arraycopy(inData, 0, dataSamples, mLastDataSampleIndex, dataSampleStride);
1115
1116        if (mXOffset != 0 || mYOffset != 0) {
1117            int index = mLastEventTimeNanoSampleIndex;
1118            for (int i = 0; i < numPointers; i++) {
1119                dataSamples[index + SAMPLE_X] -= mXOffset;
1120                dataSamples[index + SAMPLE_Y] -= mYOffset;
1121                index += NUM_SAMPLE_DATA;
1122            }
1123        }
1124
1125        mMetaState |= metaState;
1126
1127        if (DEBUG_POINTERS) {
1128            StringBuilder sb = new StringBuilder(128);
1129            sb.append("Add:");
1130            for (int i = 0; i < mNumPointers; i++) {
1131                sb.append(" #");
1132                sb.append(getPointerId(i));
1133                sb.append("(");
1134                sb.append(getX(i));
1135                sb.append(",");
1136                sb.append(getY(i));
1137                sb.append(")");
1138            }
1139            Log.v("MotionEvent", sb.toString());
1140        }
1141    }
1142
1143    @Override
1144    public String toString() {
1145        return "MotionEvent{" + Integer.toHexString(System.identityHashCode(this))
1146            + " action=" + mAction + " x=" + getX()
1147            + " y=" + getY() + " pressure=" + getPressure() + " size=" + getSize() + "}";
1148    }
1149
1150    public static final Parcelable.Creator<MotionEvent> CREATOR
1151            = new Parcelable.Creator<MotionEvent>() {
1152        public MotionEvent createFromParcel(Parcel in) {
1153            final int NP = in.readInt();
1154            final int NS = in.readInt();
1155            final int NI = NP * NS * NUM_SAMPLE_DATA;
1156
1157            MotionEvent ev = obtain(NP, NS);
1158            ev.mNumPointers = NP;
1159            ev.mNumSamples = NS;
1160
1161            ev.mDownTimeNano = in.readLong();
1162            ev.mAction = in.readInt();
1163            ev.mXOffset = in.readFloat();
1164            ev.mYOffset = in.readFloat();
1165            ev.mXPrecision = in.readFloat();
1166            ev.mYPrecision = in.readFloat();
1167            ev.mDeviceId = in.readInt();
1168            ev.mEdgeFlags = in.readInt();
1169            ev.mMetaState = in.readInt();
1170
1171            final int[] pointerIdentifiers = ev.mPointerIdentifiers;
1172            for (int i = 0; i < NP; i++) {
1173                pointerIdentifiers[i] = in.readInt();
1174            }
1175
1176            final long[] eventTimeNanoSamples = ev.mEventTimeNanoSamples;
1177            for (int i = 0; i < NS; i++) {
1178                eventTimeNanoSamples[i] = in.readLong();
1179            }
1180
1181            final float[] dataSamples = ev.mDataSamples;
1182            for (int i = 0; i < NI; i++) {
1183                dataSamples[i] = in.readFloat();
1184            }
1185
1186            ev.mLastEventTimeNanoSampleIndex = NS - 1;
1187            ev.mLastDataSampleIndex = (NS - 1) * NP * NUM_SAMPLE_DATA;
1188            return ev;
1189        }
1190
1191        public MotionEvent[] newArray(int size) {
1192            return new MotionEvent[size];
1193        }
1194    };
1195
1196    public int describeContents() {
1197        return 0;
1198    }
1199
1200    public void writeToParcel(Parcel out, int flags) {
1201        final int NP = mNumPointers;
1202        final int NS = mNumSamples;
1203        final int NI = NP * NS * NUM_SAMPLE_DATA;
1204
1205        out.writeInt(NP);
1206        out.writeInt(NS);
1207
1208        out.writeLong(mDownTimeNano);
1209        out.writeInt(mAction);
1210        out.writeFloat(mXOffset);
1211        out.writeFloat(mYOffset);
1212        out.writeFloat(mXPrecision);
1213        out.writeFloat(mYPrecision);
1214        out.writeInt(mDeviceId);
1215        out.writeInt(mEdgeFlags);
1216        out.writeInt(mMetaState);
1217
1218        final int[] pointerIdentifiers = mPointerIdentifiers;
1219        for (int i = 0; i < NP; i++) {
1220            out.writeInt(pointerIdentifiers[i]);
1221        }
1222
1223        final long[] eventTimeNanoSamples = mEventTimeNanoSamples;
1224        for (int i = 0; i < NS; i++) {
1225            out.writeLong(eventTimeNanoSamples[i]);
1226        }
1227
1228        final float[] dataSamples = mDataSamples;
1229        for (int i = 0; i < NI; i++) {
1230            out.writeFloat(dataSamples[i]);
1231        }
1232    }
1233}
1234